KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jode > obfuscator > Identifier


1 /* Identifier Copyright (C) 1999-2002 Jochen Hoenicke.
2  *
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; either version 2, or (at your option)
6  * any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; see the file COPYING. If not, write to
15  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
16  *
17  * $Id: Identifier.java.in,v 1.4.2.2 2002/05/28 17:34:14 hoenicke Exp $
18  */

19
20 package jode.obfuscator;
21 import jode.GlobalOptions;
22 import java.io.*;
23 import java.util.Map JavaDoc;
24 import java.util.Iterator JavaDoc;
25
26 public abstract class Identifier {
27     /**
28      * This is a doubly list of identifiers, that must have always
29      * have the same names, and same preserved settings.
30      */

31     private Identifier right = null;
32     private Identifier left = null;
33
34     private boolean reachable = false;
35     private boolean preserved = false;
36
37     private String JavaDoc alias = null;
38     private boolean wasAliased = false;
39     
40     public Identifier(String JavaDoc alias) {
41     this.alias = alias;
42     }
43
44
45     /**
46      * Returns true, if this identifier is reachable in some way, false if it
47      * is dead and can be removed.
48      */

49     public final boolean isReachable() {
50     return reachable;
51     }
52
53     /**
54      * true, if this identifier must preserve its name, false if the
55      * name may be obfuscated.
56      */

57     public final boolean isPreserved() {
58     return preserved;
59     }
60
61     /**
62      * Marks this identifier as preserved. This will also make the
63      * identifier reachable, if it isn't already.
64      *
65      * You shouldn't call this directly, but use setPreserved instead.
66      */

67     protected void setSinglePreserved() {
68     }
69
70     /**
71      * Marks this identifier as reachable.
72      *
73      * You should override this method for method identifier, which may
74      * mark other methods as reachable.
75      *
76      * You shouldn't call this directly, but use setReachable instead.
77      */

78     protected void setSingleReachable() {
79     if (getParent() != null)
80         getParent().setReachable();
81     }
82
83     /**
84      * Mark all shadows as reachable.
85      */

86     public void setReachable() {
87     if (!reachable) {
88         reachable = true;
89         setSingleReachable();
90     }
91     }
92
93     /**
94      * Mark all shadows as preserved.
95      */

96     public void setPreserved() {
97     if (!preserved) {
98         preserved = true;
99         Identifier ptr = this;
100         while (ptr != null) {
101         ptr.setSinglePreserved();
102         ptr = ptr.left;
103         }
104         ptr = right;
105         while (ptr != null) {
106         ptr.setSinglePreserved();
107         ptr = ptr.right;
108         }
109     }
110     }
111
112     public Identifier getRepresentative() {
113     Identifier ptr = this;
114     while (ptr.left != null)
115         ptr = ptr.left;
116     return ptr;
117     }
118
119     public final boolean isRepresentative() {
120     return left == null;
121     }
122
123     public final boolean wasAliased() {
124     return getRepresentative().wasAliased;
125     }
126
127     public final void setAlias(String JavaDoc name) {
128     if (name != null) {
129         Identifier rep = getRepresentative();
130         rep.wasAliased = true;
131         rep.alias = name;
132     }
133     }
134
135     public final String JavaDoc getAlias() {
136     return getRepresentative().alias;
137     }
138
139     /**
140      * Mark that this identifier and the given identifier must always have
141      * the same name.
142      */

143     public void addShadow(Identifier orig) {
144     if (isPreserved() && !orig.isPreserved())
145         orig.setPreserved();
146     else if (!isPreserved() && orig.isPreserved())
147         setPreserved();
148     
149     Identifier ptr = this;
150     while (ptr.right != null)
151         ptr = ptr.right;
152
153     /* Check if orig is already on the ptr chain */
154     Identifier check = orig;
155     while (check.right != null)
156         check = check.right;
157     if (check == ptr)
158         return;
159
160     while (orig.left != null)
161         orig = orig.left;
162     ptr.right = orig;
163     orig.left = ptr;
164     }
165
166     static int serialnr = 0;
167
168     public void buildTable(Renamer renameRule) {
169     if (!isReachable()
170         && (Main.stripping & Main.STRIP_UNREACH) != 0)
171         return;
172
173     if (isPreserved()) {
174         if (GlobalOptions.verboseLevel > 4)
175         GlobalOptions.err.println(toString() + " is preserved");
176     } else {
177         Identifier rep = getRepresentative();
178         if (!rep.wasAliased) {
179         rep.wasAliased = true;
180
181         // set alias to empty string, so it won't conflict!
182
rep.alias = "";
183         Iterator JavaDoc aliases = renameRule.generateNames(this);
184         next_alias:
185         for (;;) {
186             String JavaDoc newAlias = (String JavaDoc) aliases.next();
187             Identifier ptr = rep;
188             while (ptr != null) {
189             if (ptr.conflicting(newAlias))
190                 continue next_alias;
191             ptr = ptr.right;
192             }
193             setAlias(newAlias.toString());
194             break;
195         }
196         }
197     }
198     for (Iterator JavaDoc i = getChilds(); i.hasNext(); )
199         ((Identifier)i.next()).buildTable(renameRule);
200     }
201
202     public void writeTable(Map JavaDoc table, boolean reversed) {
203     if (!isReachable()
204         && (Main.stripping & Main.STRIP_UNREACH) != 0)
205         return;
206
207     if (getAlias().length() != 0) {
208         String JavaDoc name = getName();
209         Identifier outer = getParent();
210         while (outer != null && outer.getAlias().length() == 0) {
211         if (outer.getName().length() > 0)
212             name = outer.getName() + "." + name;
213         outer = outer.getParent();
214         }
215         if (reversed)
216         table.put(getFullAlias(), name);
217         else
218         table.put(getFullName(), getAlias());
219     }
220
221     for (Iterator JavaDoc i = getChilds(); i.hasNext(); )
222         ((Identifier)i.next()).writeTable(table, reversed);
223     }
224
225     public void readTable(Map JavaDoc table) {
226     Identifier rep = getRepresentative();
227     if (!rep.wasAliased) {
228         String JavaDoc newAlias = (String JavaDoc) table.get(getFullName());
229         if (newAlias != null) {
230         rep.wasAliased = true;
231         rep.setAlias(newAlias);
232         }
233     }
234     for (Iterator JavaDoc i = getChilds(); i.hasNext(); )
235         ((Identifier)i.next()).readTable(table);
236     }
237
238     public void applyPreserveRule(IdentifierMatcher preserveRule) {
239     if (preserveRule.matches(this)) {
240         System.err.println("preserving: "+this);
241         setReachable();
242         Identifier ident = this;
243         while (ident != null) {
244         ident.setPreserved();
245         ident = ident.getParent();
246         }
247     }
248     for (Iterator JavaDoc i = getChilds(); i.hasNext(); )
249         ((Identifier)i.next()).applyPreserveRule(preserveRule);
250     }
251     public abstract Iterator JavaDoc getChilds();
252     public abstract Identifier getParent();
253     public abstract String JavaDoc getName();
254     public abstract String JavaDoc getType();
255     public abstract String JavaDoc getFullName();
256     public abstract String JavaDoc getFullAlias();
257     public abstract boolean conflicting(String JavaDoc newAlias);
258
259     /**
260      * This is called by ClassBundle when it a class is added with
261      * ClassBundle.analyzeIdentifier().
262      */

263     public void analyze() {
264     }
265 }
266
Popular Tags