001: /* ===========================================================================
002: * $RCSfile: PkCl.java,v $
003: * ===========================================================================
004: *
005: * RetroGuard -- an obfuscation package for Java classfiles.
006: *
007: * Copyright (c) 1998-2006 Mark Welsh (markw@retrologic.com)
008: *
009: * This program can be redistributed and/or modified under the terms of the
010: * Version 2 of the GNU General Public License as published by the Free
011: * Software Foundation.
012: *
013: * This program is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016: * GNU General Public License for more details.
017: *
018: */
019:
020: package COM.rl.obf;
021:
022: import java.io.*;
023: import java.lang.reflect.*;
024: import java.util.*;
025: import COM.rl.util.*;
026: import COM.rl.obf.classfile.*;
027:
028: /**
029: * Base to package and class tree item.
030: *
031: * @author Mark Welsh
032: */
033: abstract public class PkCl extends TreeItem {
034: // Constants -------------------------------------------------------------
035:
036: // Fields ----------------------------------------------------------------
037: /** Owns a list of classes. */
038: protected Hashtable cls = new Hashtable();
039:
040: // Class Methods ---------------------------------------------------------
041:
042: // Instance Methods ------------------------------------------------------
043: /** Ctor. */
044: public PkCl(TreeItem parent, String name) {
045: super (parent, name);
046: }
047:
048: /** Get a class by name. */
049: public Cl getClass(String name) throws Exception {
050: return (Cl) cls.get(name);
051: }
052:
053: /** Get a class by obfuscated name. */
054: public Cl getObfClass(String name) throws Exception {
055: for (Enumeration enm = cls.elements(); enm.hasMoreElements();) {
056: Cl cl = (Cl) enm.nextElement();
057: if (name.equals(cl.getOutName())) {
058: return cl;
059: }
060: }
061: return null;
062: }
063:
064: /** Get an Enumeration of classes directly beneath this PkCl. */
065: public Enumeration getClassEnum() {
066: return cls.elements();
067: }
068:
069: /** Get an Enumeration of all classes (outer and inner) in the tree beneath this PkCl. */
070: public Enumeration getAllClassEnum() {
071: Vector allClasses = new Vector();
072: addAllClasses(allClasses);
073: return allClasses.elements();
074: }
075:
076: /** List classes and recursively compose a list of all inner classes. */
077: protected void addAllClasses(Vector allClasses) {
078: for (Enumeration enm = cls.elements(); enm.hasMoreElements();) {
079: Cl cl = (Cl) enm.nextElement();
080: allClasses.addElement(cl);
081: cl.addAllClasses(allClasses);
082: }
083: }
084:
085: /** Return number of classes. */
086: public int getClassCount() {
087: return cls.size();
088: }
089:
090: /** Add a class to the list of owned classes. */
091: abstract public Cl addClass(String name, String super Name,
092: String[] interfaceNames, int access) throws Exception;
093:
094: /** Add a class to the list of owned classes. */
095: public Cl addClass(boolean isInnerClass, String name,
096: String super Name, String[] interfaceNames, int access)
097: throws Exception {
098: Cl cl = getClass(name);
099:
100: // Remove placeholder if present
101: PlaceholderCl plClassItem = null;
102: if (cl instanceof PlaceholderCl) {
103: plClassItem = (PlaceholderCl) cl;
104: cls.remove(name);
105: cl = null;
106: }
107:
108: // Add the class, if not already present
109: if (cl == null) {
110: cl = new Cl(this , isInnerClass, name, super Name,
111: interfaceNames, access);
112: cls.put(name, cl);
113: }
114:
115: // Copy over the inner class data from the placeholder, if any
116: if (plClassItem != null) {
117: for (Enumeration enm = plClassItem.getClassEnum(); enm
118: .hasMoreElements();) {
119: Cl innerCl = (Cl) enm.nextElement();
120: innerCl.setParent(cl);
121: cl.addClass(innerCl);
122: }
123: }
124: return cl;
125: }
126:
127: /** Add a placeholder class to our list of owned classes, to be replaced later by the full class. */
128: abstract public Cl addPlaceholderClass(String name)
129: throws Exception;
130:
131: /** Add a placeholder class to our list of owned classes, to be replaced later by the full class. */
132: public Cl addPlaceholderClass(boolean isInnerClass, String name)
133: throws Exception {
134: Cl cl = getClass(name);
135: if (cl == null) {
136: cl = new PlaceholderCl(this , isInnerClass, name);
137: cls.put(name, cl);
138: }
139: return cl;
140: }
141:
142: /** Generate unique obfuscated names for this namespace. */
143: public void generateNames() throws Exception {
144: generateNames(cls);
145: }
146:
147: /** Generate unique obfuscated names for a given namespace. */
148: protected void generateNames(Hashtable hash) throws Exception {
149: Vector vec = new Vector();
150: for (Enumeration enm = hash.elements(); enm.hasMoreElements();) {
151: TreeItem ti = (TreeItem) enm.nextElement();
152: if (ti.isFixed()) {
153: vec.addElement(ti.getOutName());
154: }
155: }
156: String[] noObfNames = new String[vec.size()];
157: for (int i = 0; i < noObfNames.length; i++) {
158: noObfNames[i] = (String) vec.elementAt(i);
159: }
160: NameMaker nm = new KeywordNameMaker(noObfNames, false, true);
161: for (Enumeration enm = hash.elements(); enm.hasMoreElements();) {
162: TreeItem ti = (TreeItem) enm.nextElement();
163: if (!ti.isFixed()) {
164: ti.setOutName(nm.nextName(null));
165: }
166: }
167: }
168: }
|