Source Code Cross Referenced for Cl.java in  » Development » RetroGuard » COM » rl » obf » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Development » RetroGuard » COM.rl.obf 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /* ===========================================================================
0002:         * $RCSfile: Cl.java,v $
0003:         * ===========================================================================
0004:         *
0005:         * RetroGuard -- an obfuscation package for Java classfiles.
0006:         *
0007:         * Copyright (c) 1998-2006 Mark Welsh (markw@retrologic.com)
0008:         *
0009:         * This program can be redistributed and/or modified under the terms of the 
0010:         * Version 2 of the GNU General Public License as published by the Free 
0011:         * Software Foundation.
0012:         *
0013:         * This program is distributed in the hope that it will be useful,
0014:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
0015:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
0016:         * GNU General Public License for more details.
0017:         *
0018:         */
0019:
0020:        package COM.rl.obf;
0021:
0022:        import java.io.*;
0023:        import java.lang.reflect.*;
0024:        import java.util.*;
0025:        import COM.rl.util.*;
0026:        import COM.rl.obf.classfile.*;
0027:
0028:        /**
0029:         * Tree item representing a class or interface.
0030:         *
0031:         * @author      Mark Welsh
0032:         */
0033:        public class Cl extends PkCl implements  NameListUp, NameListDown {
0034:            // Constants -------------------------------------------------------------
0035:
0036:            // Fields ----------------------------------------------------------------
0037:            private Hashtable mds = new Hashtable(); // Owns a list of methods
0038:            private Hashtable mdsSpecial = new Hashtable(); // Owns a list of special methods
0039:            private Hashtable fds = new Hashtable(); // Owns a list of fields
0040:            private boolean isResolved = false; // Has the class been resolved already?
0041:            private boolean isScanned = false; // Has the class been scanned already?
0042:            private String super Class; // Our superclass name
0043:            private String[] super Interfaces; // Names of implemented interfaces
0044:            private boolean isInnerClass; // Is this an inner class?
0045:            private Vector nameListUps = new Vector(); // NameListUp interfaces for super-class/interfaces
0046:            private Vector nameListDowns = new Vector(); // NameListDown interfaces for derived class/interfaces
0047:            private boolean isNoWarn = false; // Are danger-method warnings suppressed?
0048:            private Vector warningList = null; // Danger-method warnings
0049:
0050:            public static int nameSpace = 0;
0051:            private static NameMaker methodNameMaker;
0052:            private static NameMaker fieldNameMaker;
0053:
0054:            // Class Methods ---------------------------------------------------------
0055:
0056:            // Instance Methods ------------------------------------------------------
0057:            /** Ctor. */
0058:            public Cl(TreeItem parent, boolean isInnerClass, String name,
0059:                    String super Class, String[] super Interfaces, int access)
0060:                    throws Exception {
0061:                super (parent, name);
0062:                this .super Class = super Class;
0063:                this .super Interfaces = super Interfaces;
0064:                this .isInnerClass = isInnerClass;
0065:                this .access = access;
0066:                if (parent == null || "".equals(name)) {
0067:                    System.err
0068:                            .println("Internal error: class must have parent and name");
0069:                }
0070:                if (parent instanceof  Cl) {
0071:                    sep = ClassFile.SEP_INNER;
0072:                }
0073:
0074:                // Do not obfuscate anonymous inner classes
0075:                if (isInnerClass && name != null && name.length() > 0
0076:                        && Character.isDigit(name.charAt(0))) {
0077:                    setOutName(getInName());
0078:                }
0079:            }
0080:
0081:            /** Is this an inner class? */
0082:            public boolean isInnerClass() {
0083:                return isInnerClass;
0084:            }
0085:
0086:            /** Suppress warnings. */
0087:            public void setNoWarn() {
0088:                isNoWarn = true;
0089:            }
0090:
0091:            /** Add class's warning. */
0092:            public void setWarnings(ClassFile cf) throws Exception {
0093:                if (warningList == null) {
0094:                    warningList = new Vector();
0095:                }
0096:                warningList = cf.listDangerMethods(warningList);
0097:            }
0098:
0099:            /** Do we have non-suppressed warnings? */
0100:            public boolean hasWarnings() {
0101:                return (!isNoWarn && warningList != null && warningList.size() > 0);
0102:            }
0103:
0104:            /** Log this class's warnings. */
0105:            public void logWarnings(PrintWriter log) {
0106:                if (hasWarnings()) {
0107:                    for (Enumeration enm = warningList.elements(); enm
0108:                            .hasMoreElements();) {
0109:                        log.println("# " + (String) enm.nextElement());
0110:                    }
0111:                }
0112:            }
0113:
0114:            /** Get a method by name. */
0115:            public Md getMethod(String name, String descriptor)
0116:                    throws Exception {
0117:                return (Md) mds.get(name + descriptor);
0118:            }
0119:
0120:            /** Get a special method by name. */
0121:            public Md getMethodSpecial(String name, String descriptor)
0122:                    throws Exception {
0123:                return (Md) mdsSpecial.get(name + descriptor);
0124:            }
0125:
0126:            /** Get all methods with obfuscated name. */
0127:            public Enumeration getObfMethods(String name) throws Exception {
0128:                Vector mdsMatch = new Vector();
0129:                for (Enumeration enm = mds.elements(); enm.hasMoreElements();) {
0130:                    Md md = (Md) enm.nextElement();
0131:                    if (name.equals(md.getOutName())) {
0132:                        mdsMatch.addElement(md);
0133:                    }
0134:                }
0135:                return mdsMatch.elements();
0136:            }
0137:
0138:            /** Get a field by name. */
0139:            public Fd getField(String name) throws Exception {
0140:                return (Fd) fds.get(name);
0141:            }
0142:
0143:            /** Get an Enumeration of methods. */
0144:            public Enumeration getMethodEnum() throws Exception {
0145:                return mds.elements();
0146:            }
0147:
0148:            /** Get an Enumeration of fields. */
0149:            public Enumeration getFieldEnum() throws Exception {
0150:                return fds.elements();
0151:            }
0152:
0153:            /** Return this Cl's superclass Cl */
0154:            public Cl getSuperCl() throws Exception {
0155:                if (super Class != null) {
0156:                    return classTree.getCl(super Class);
0157:                } else {
0158:                    return null;
0159:                }
0160:            }
0161:
0162:            /** Return Enumeration of this Cl's super-interfaces */
0163:            public Enumeration getSuperInterfaces() throws Exception {
0164:                Vector v = new Vector();
0165:                if (super Interfaces != null) {
0166:                    for (int i = 0; i < super Interfaces.length; i++) {
0167:                        Cl interfaceItem = classTree.getCl(super Interfaces[i]);
0168:                        if (interfaceItem != null) {
0169:                            v.addElement(interfaceItem);
0170:                        }
0171:                    }
0172:                }
0173:                return v.elements();
0174:            }
0175:
0176:            /** Does this internal class have the specified class or interface 
0177:                in its super or interface chain? */
0178:            protected boolean hasAsSuperInt(String queryName,
0179:                    boolean checkInterfaces) {
0180:                try {
0181:                    // Special case: is this java/lang/Object?
0182:                    if (super Class == null)
0183:                        return false;
0184:                    // Check our parents
0185:                    if (super Class.equals(queryName))
0186:                        return true;
0187:                    if (checkInterfaces) {
0188:                        if (super Interfaces != null) {
0189:                            for (int i = 0; i < super Interfaces.length; i++) {
0190:                                if (queryName.equals(super Interfaces[i]))
0191:                                    return true;
0192:                            }
0193:                        }
0194:                    }
0195:                    // Nothing, so recurse up through parents
0196:                    Cl super ClInt = classTree.getCl(super Class);
0197:                    if (super ClInt != null) {
0198:                        if (super ClInt
0199:                                .hasAsSuperInt(queryName, checkInterfaces))
0200:                            return true;
0201:                    } else {
0202:                        Class super ClExt = Class.forName(ClassFile
0203:                                .translate(super Class));
0204:                        if (super ClExt != null) {
0205:                            if (hasAsSuperExt(queryName, checkInterfaces,
0206:                                    this .classTree, super ClExt))
0207:                                return true;
0208:                        }
0209:                    }
0210:                    if (checkInterfaces) {
0211:                        if (super Interfaces != null) {
0212:                            for (int i = 0; i < super Interfaces.length; i++) {
0213:                                Cl interClInt = classTree
0214:                                        .getCl(super Interfaces[i]);
0215:                                if (interClInt != null) {
0216:                                    if (interClInt.hasAsSuperInt(queryName,
0217:                                            checkInterfaces))
0218:                                        return true;
0219:                                } else {
0220:                                    Class interClExt = Class.forName(ClassFile
0221:                                            .translate(super Interfaces[i]));
0222:                                    if (interClExt != null) {
0223:                                        if (hasAsSuperExt(queryName,
0224:                                                checkInterfaces,
0225:                                                this .classTree, interClExt))
0226:                                            return true;
0227:                                    }
0228:                                }
0229:                            }
0230:                        }
0231:                    }
0232:                } catch (Exception e) {
0233:                    // fall thru
0234:                }
0235:                return false;
0236:            }
0237:
0238:            /** Does this class have the specified class or interface in its super 
0239:                or interface chain? */
0240:            protected static boolean hasAsSuperExt(String queryName,
0241:                    boolean checkInterfaces, ClassTree classTree, Class clExt) {
0242:                try {
0243:                    // Special case: is this java/lang/Object?
0244:                    if (clExt == null
0245:                            || clExt.getName().equals("java.lang.Object"))
0246:                        return false;
0247:                    // Check our parents
0248:                    String queryNameExt = ClassFile.translate(queryName);
0249:                    Class super Class = clExt.getSuperclass();
0250:                    Class[] super Interfaces = clExt.getInterfaces();
0251:                    if (queryNameExt.equals(super Class.getName()))
0252:                        return true;
0253:                    if (checkInterfaces) {
0254:                        if (super Interfaces != null) {
0255:                            for (int i = 0; i < super Interfaces.length; i++) {
0256:                                if (queryNameExt.equals(super Interfaces[i]
0257:                                        .getName()))
0258:                                    return true;
0259:                            }
0260:                        }
0261:                    }
0262:                    // Nothing, so recurse up through parents
0263:                    Cl super ClInt = classTree.getCl(ClassFile
0264:                            .backTranslate(super Class.getName()));
0265:                    if (super ClInt != null) {
0266:                        if (super ClInt
0267:                                .hasAsSuperInt(queryName, checkInterfaces))
0268:                            return true;
0269:                    } else {
0270:                        Class super ClExt = super Class;
0271:                        if (super ClExt != null) {
0272:                            if (hasAsSuperExt(queryName, checkInterfaces,
0273:                                    classTree, super ClExt))
0274:                                return true;
0275:                        }
0276:                    }
0277:                    if (checkInterfaces) {
0278:                        if (super Interfaces != null) {
0279:                            for (int i = 0; i < super Interfaces.length; i++) {
0280:                                Cl interClInt = classTree.getCl(ClassFile
0281:                                        .backTranslate(super Interfaces[i]
0282:                                                .getName()));
0283:                                if (interClInt != null) {
0284:                                    if (interClInt.hasAsSuperInt(queryName,
0285:                                            checkInterfaces))
0286:                                        return true;
0287:                                } else {
0288:                                    Class interClExt = super Interfaces[i];
0289:                                    if (interClExt != null) {
0290:                                        if (hasAsSuperExt(queryName,
0291:                                                checkInterfaces, classTree,
0292:                                                interClExt))
0293:                                            return true;
0294:                                    }
0295:                                }
0296:                            }
0297:                        }
0298:                    }
0299:                } catch (Exception e) {
0300:                    // fall thru
0301:                }
0302:                return false;
0303:            }
0304:
0305:            /** Does this class have the specified class or interface in its super 
0306:                or interface chain? */
0307:            public boolean hasAsSuperOrInterface(String queryName) {
0308:                return hasAsSuperInt(queryName, true);
0309:            }
0310:
0311:            /** Does this class have the specified class in its super chain? */
0312:            public boolean hasAsSuper(String queryName) {
0313:                return hasAsSuperInt(queryName, false);
0314:            }
0315:
0316:            /** Add an inner class. */
0317:            public Cl addClass(String name, String super Name,
0318:                    String[] interfaceNames, int access) throws Exception {
0319:                return addClass(true, name, super Name, interfaceNames, access);
0320:            }
0321:
0322:            /** Add an inner class, used when copying inner classes from a placeholder. */
0323:            public Cl addClass(Cl cl) throws Exception {
0324:                cls.put(cl.getInName(), cl);
0325:                return cl;
0326:            }
0327:
0328:            /** Add a placeholder class. */
0329:            public Cl addPlaceholderClass(String name) throws Exception {
0330:                return addPlaceholderClass(true, name);
0331:            }
0332:
0333:            /** Add a method. */
0334:            public Md addMethod(ClassFile cf, MethodInfo methodInfo,
0335:                    boolean enableTrim) throws Exception {
0336:                Md md = addMethod(methodInfo.isSynthetic(), methodInfo
0337:                        .getName(), methodInfo.getDescriptor(), methodInfo
0338:                        .getAccessFlags());
0339:                // Construct method's reference list
0340:                if (enableTrim) {
0341:                    md.findRefs(cf, methodInfo);
0342:                }
0343:                return md;
0344:            }
0345:
0346:            /** Add a method. */
0347:            public Md addMethod(boolean isSynthetic, String name,
0348:                    String descriptor, int accessFlags) throws Exception {
0349:                // Store <init> and <clinit> methods separately - needed only for 
0350:                // reference tracking ('.option trim')
0351:                Md md;
0352:                if (name.charAt(0) == '<') {
0353:                    md = getMethodSpecial(name, descriptor);
0354:                    if (md == null) {
0355:                        md = new Md(this , isSynthetic, name, descriptor,
0356:                                accessFlags);
0357:                        mdsSpecial.put(name + descriptor, md);
0358:                    }
0359:                } else {
0360:                    md = getMethod(name, descriptor);
0361:                    if (md == null) {
0362:                        md = new Md(this , isSynthetic, name, descriptor,
0363:                                accessFlags);
0364:                        mds.put(name + descriptor, md);
0365:                    }
0366:                }
0367:                return md;
0368:            }
0369:
0370:            /** Add a field. */
0371:            public Fd addField(ClassFile cf, FieldInfo fieldInfo,
0372:                    boolean enableTrim) throws Exception {
0373:                Fd fd = addField(fieldInfo.isSynthetic(), fieldInfo.getName(),
0374:                        fieldInfo.getDescriptor(), fieldInfo.getAccessFlags());
0375:                // Construct field's reference list
0376:                if (enableTrim) {
0377:                    fd.findRefs(cf, fieldInfo);
0378:                }
0379:                return fd;
0380:            }
0381:
0382:            /** Add a field. */
0383:            public Fd addField(boolean isSynthetic, String name,
0384:                    String descriptor, int access) throws Exception {
0385:                Fd fd = getField(name);
0386:                if (fd == null) {
0387:                    fd = new Fd(this , isSynthetic, name, descriptor, access);
0388:                    fds.put(name, fd);
0389:                }
0390:                return fd;
0391:            }
0392:
0393:            /** Prepare for resolve of a class entry by resetting flags. */
0394:            public void resetResolve() throws Exception {
0395:                isScanned = false;
0396:                isResolved = false;
0397:                nameListDowns.removeAllElements();
0398:            }
0399:
0400:            /** Set up reverse list of reserved names prior to resolving classes. */
0401:            public void setupNameListDowns() throws Exception {
0402:                // Special case: we are java/lang/Object
0403:                if (super Class == null)
0404:                    return;
0405:
0406:                // Add this class as a NameListDown to the super and each interface, if they are in the JAR
0407:                Cl super ClassItem = classTree.getCl(super Class);
0408:                if (super ClassItem != null) {
0409:                    super ClassItem.nameListDowns.addElement(this );
0410:                }
0411:                if (super Interfaces != null) {
0412:                    for (int i = 0; i < super Interfaces.length; i++) {
0413:                        Cl interfaceItem = classTree.getCl(super Interfaces[i]);
0414:                        if (interfaceItem != null) {
0415:                            interfaceItem.nameListDowns.addElement(this );
0416:                        }
0417:                    }
0418:                }
0419:            }
0420:
0421:            /**
0422:             * Resolve a class entry - set obfuscation permissions based on super class and interfaces.
0423:             * Overload method and field names maximally.
0424:             */
0425:            public void resolveOptimally() throws Exception {
0426:                // Already processed, then do nothing
0427:                if (!isResolved) {
0428:                    // Get lists of method and field names in inheritance namespace
0429:                    Vector methods = new Vector();
0430:                    Vector fields = new Vector();
0431:                    scanNameSpaceExcept(null, methods, fields);
0432:                    String[] methodNames = new String[methods.size()];
0433:                    for (int i = 0; i < methodNames.length; i++) {
0434:                        methodNames[i] = (String) methods.elementAt(i);
0435:                    }
0436:                    String[] fieldNames = new String[fields.size()];
0437:                    for (int i = 0; i < fieldNames.length; i++) {
0438:                        fieldNames[i] = (String) fields.elementAt(i);
0439:                    }
0440:
0441:                    // Create new name-makers for the namespace
0442:                    methodNameMaker = new KeywordNameMaker(methodNames);
0443:                    fieldNameMaker = new KeywordNameMaker(fieldNames);
0444:
0445:                    // Resolve a full name space
0446:                    resolveNameSpaceExcept(null);
0447:
0448:                    // and move to next
0449:                    nameSpace++;
0450:                }
0451:            }
0452:
0453:            // Get lists of method and field names in inheritance namespace
0454:            private void scanNameSpaceExcept(Cl ignoreCl, Vector methods,
0455:                    Vector fields) throws Exception {
0456:                // Special case: we are java/lang/Object
0457:                if (super Class == null)
0458:                    return;
0459:
0460:                // Traverse one step in each direction in name space, scanning
0461:                if (!isScanned) {
0462:                    // First step up to super classes, scanning them
0463:                    Cl super Cl = classTree.getCl(super Class);
0464:                    if (super Cl != null) // internal to JAR
0465:                    {
0466:                        if (super Cl != ignoreCl) {
0467:                            super Cl.scanNameSpaceExcept(this , methods, fields);
0468:                        }
0469:                    } else // external to JAR
0470:                    {
0471:                        scanExtSupers(super Class, methods, fields);
0472:                    }
0473:                    if (super Interfaces != null) {
0474:                        for (int i = 0; i < super Interfaces.length; i++) {
0475:                            Cl interfaceItem = classTree
0476:                                    .getCl(super Interfaces[i]);
0477:                            if (interfaceItem != null
0478:                                    && interfaceItem != ignoreCl) {
0479:                                interfaceItem.scanNameSpaceExcept(this ,
0480:                                        methods, fields);
0481:                            }
0482:                        }
0483:                    }
0484:
0485:                    // Next, scan ourself
0486:                    if (!isScanned) {
0487:                        scanThis(methods, fields);
0488:
0489:                        // Signal class has been scanned
0490:                        isScanned = true;
0491:                    }
0492:
0493:                    // Finally step down to derived classes, resolving them
0494:                    for (Enumeration clEnum = nameListDowns.elements(); clEnum
0495:                            .hasMoreElements();) {
0496:                        Cl cl = (Cl) clEnum.nextElement();
0497:                        if (cl != ignoreCl) {
0498:                            cl.scanNameSpaceExcept(this , methods, fields);
0499:                        }
0500:                    }
0501:                }
0502:            }
0503:
0504:            // Get lists of method and field names in inheritance namespace
0505:            private void scanExtSupers(String name, Vector methods,
0506:                    Vector fields) throws Exception {
0507:                Class extClass = Class.forName(ClassFile.translate(name));
0508:
0509:                // Get public methods and fields from supers and interfaces up the tree
0510:                Method[] allPubMethods = extClass.getMethods();
0511:                if (allPubMethods != null) {
0512:                    for (int i = 0; i < allPubMethods.length; i++) {
0513:                        String methodName = allPubMethods[i].getName();
0514:                        if (methods.indexOf(methodName) == -1) {
0515:                            methods.addElement(methodName);
0516:                        }
0517:                    }
0518:                }
0519:                Field[] allPubFields = extClass.getFields();
0520:                if (allPubFields != null) {
0521:                    for (int i = 0; i < allPubFields.length; i++) {
0522:                        String fieldName = allPubFields[i].getName();
0523:                        if (fields.indexOf(fieldName) == -1) {
0524:                            fields.addElement(fieldName);
0525:                        }
0526:                    }
0527:                }
0528:                // Go up the super hierarchy, adding all non-public methods/fields
0529:                while (extClass != null) {
0530:                    Method[] allClassMethods = extClass.getDeclaredMethods();
0531:                    if (allClassMethods != null) {
0532:                        for (int i = 0; i < allClassMethods.length; i++) {
0533:                            if (!Modifier.isPublic(allClassMethods[i]
0534:                                    .getModifiers())) {
0535:                                String methodName = allClassMethods[i]
0536:                                        .getName();
0537:                                if (methods.indexOf(methodName) == -1) {
0538:                                    methods.addElement(methodName);
0539:                                }
0540:                            }
0541:                        }
0542:                    }
0543:                    Field[] allClassFields = extClass.getDeclaredFields();
0544:                    if (allClassFields != null) {
0545:                        for (int i = 0; i < allClassFields.length; i++) {
0546:                            if (!Modifier.isPublic(allClassFields[i]
0547:                                    .getModifiers())) {
0548:                                String fieldName = allClassFields[i].getName();
0549:                                if (fields.indexOf(fieldName) == -1) {
0550:                                    fields.addElement(fieldName);
0551:                                }
0552:                            }
0553:                        }
0554:                    }
0555:                    extClass = extClass.getSuperclass();
0556:                }
0557:            }
0558:
0559:            // Add method and field names from this class to the lists
0560:            private void scanThis(Vector methods, Vector fields)
0561:                    throws Exception {
0562:                for (Enumeration mdEnum = mds.elements(); mdEnum
0563:                        .hasMoreElements();) {
0564:                    Md md = (Md) mdEnum.nextElement();
0565:                    if (md.isFixed()) {
0566:                        String name = md.getOutName();
0567:                        if (methods.indexOf(name) == -1) {
0568:                            methods.addElement(name);
0569:                        }
0570:                    }
0571:                }
0572:                for (Enumeration fdEnum = fds.elements(); fdEnum
0573:                        .hasMoreElements();) {
0574:                    Fd fd = (Fd) fdEnum.nextElement();
0575:                    if (fd.isFixed()) {
0576:                        String name = fd.getOutName();
0577:                        if (fields.indexOf(name) == -1) {
0578:                            fields.addElement(name);
0579:                        }
0580:                    }
0581:                }
0582:            }
0583:
0584:            // Resolve an entire inheritance name space optimally.
0585:            private void resolveNameSpaceExcept(Cl ignoreCl) throws Exception {
0586:                // Special case: we are java/lang/Object
0587:                if (super Class == null)
0588:                    return;
0589:
0590:                // Traverse one step in each direction in name space, resolving
0591:                if (!isResolved) {
0592:                    // First step up to super classes, resolving them, since we depend on them
0593:                    Cl super Cl = classTree.getCl(super Class);
0594:                    if (super Cl != null && super Cl != ignoreCl) {
0595:                        super Cl.resolveNameSpaceExcept(this );
0596:                    }
0597:                    if (super Interfaces != null) {
0598:                        for (int i = 0; i < super Interfaces.length; i++) {
0599:                            Cl interfaceItem = classTree
0600:                                    .getCl(super Interfaces[i]);
0601:                            if (interfaceItem != null
0602:                                    && interfaceItem != ignoreCl) {
0603:                                interfaceItem.resolveNameSpaceExcept(this );
0604:                            }
0605:                        }
0606:                    }
0607:
0608:                    // Next, resolve ourself
0609:                    if (!isResolved) {
0610:                        resolveThis();
0611:
0612:                        // Signal class has been processed
0613:                        isResolved = true;
0614:                    }
0615:
0616:                    // Finally step down to derived classes, resolving them
0617:                    for (Enumeration clEnum = nameListDowns.elements(); clEnum
0618:                            .hasMoreElements();) {
0619:                        Cl cl = (Cl) clEnum.nextElement();
0620:                        if (cl != ignoreCl) {
0621:                            cl.resolveNameSpaceExcept(this );
0622:                        }
0623:                    }
0624:                }
0625:            }
0626:
0627:            // For each super interface and the super class, if it is outside DB, use reflection
0628:            // to merge its list of public/protected methods/fields --
0629:            // while for those in the DB, resolve to get the name-mapping lists
0630:            private void resolveThis() throws Exception {
0631:                // Special case: we are java/lang/Object
0632:                if (super Class == null)
0633:                    return;
0634:
0635:                Cl super ClassItem = classTree.getCl(super Class);
0636:                nameListUps
0637:                        .addElement(super ClassItem != null ? (NameListUp) super ClassItem
0638:                                : getExtNameListUp(super Class));
0639:                if (super Interfaces != null) {
0640:                    for (int i = 0; i < super Interfaces.length; i++) {
0641:                        Cl interfaceItem = classTree.getCl(super Interfaces[i]);
0642:                        nameListUps
0643:                                .addElement(interfaceItem != null ? (NameListUp) interfaceItem
0644:                                        : getExtNameListUp(super Interfaces[i]));
0645:                    }
0646:                }
0647:
0648:                // Run through each method/field in this class checking for reservations and
0649:                // obfuscating accordingly
0650:                nextMethod: for (Enumeration mdEnum = mds.elements(); mdEnum
0651:                        .hasMoreElements();) {
0652:                    Md md = (Md) mdEnum.nextElement();
0653:                    if (!md.isFixed()) {
0654:                        // Check for name reservation via derived classes
0655:                        for (Enumeration nlEnum = nameListDowns.elements(); nlEnum
0656:                                .hasMoreElements();) {
0657:                            String theOutName = ((NameListDown) nlEnum
0658:                                    .nextElement()).getMethodObfNameDown(this ,
0659:                                    md.getInName(), md.getDescriptor());
0660:                            if (theOutName != null) {
0661:                                md.setOutName(theOutName);
0662:                                continue nextMethod;
0663:                            }
0664:                        }
0665:                        // Check for name reservation via super classes
0666:                        for (Enumeration nlEnum = nameListUps.elements(); nlEnum
0667:                                .hasMoreElements();) {
0668:                            String theOutName = ((NameListUp) nlEnum
0669:                                    .nextElement()).getMethodOutNameUp(md
0670:                                    .getInName(), md.getDescriptor());
0671:                            if (theOutName != null) {
0672:                                md.setOutName(theOutName);
0673:                                md.setIsOverride();
0674:                                continue nextMethod;
0675:                            }
0676:                        }
0677:                        // If no other restrictions, obfuscate it
0678:                        md.setOutName(methodNameMaker.nextName(md
0679:                                .getDescriptor()));
0680:                    }
0681:                }
0682:                nextField: for (Enumeration fdEnum = fds.elements(); fdEnum
0683:                        .hasMoreElements();) {
0684:                    Fd fd = (Fd) fdEnum.nextElement();
0685:                    if (!fd.isFixed()) {
0686:                        // Check for name reservation via derived classes
0687:                        for (Enumeration nlEnum = nameListDowns.elements(); nlEnum
0688:                                .hasMoreElements();) {
0689:                            String theOutName = ((NameListDown) nlEnum
0690:                                    .nextElement()).getFieldObfNameDown(this ,
0691:                                    fd.getInName());
0692:                            if (theOutName != null) {
0693:                                fd.setOutName(theOutName);
0694:                                continue nextField;
0695:                            }
0696:                        }
0697:                        // Check for name reservation via super classes
0698:                        for (Enumeration nlEnum = nameListUps.elements(); nlEnum
0699:                                .hasMoreElements();) {
0700:                            String super OutName = ((NameListUp) nlEnum
0701:                                    .nextElement()).getFieldOutNameUp(fd
0702:                                    .getInName());
0703:                            if (super OutName != null) {
0704:                                fd.setOutName(super OutName);
0705:                                fd.setIsOverride();
0706:                                continue nextField;
0707:                            }
0708:                        }
0709:                        // If no other restrictions, obfuscate it
0710:                        fd.setOutName(fieldNameMaker.nextName(null));
0711:                    }
0712:                }
0713:            }
0714:
0715:            /** Get output method name from list, or null if no mapping exists. */
0716:            public String getMethodOutNameUp(String name, String descriptor)
0717:                    throws Exception {
0718:                // Check supers
0719:                for (Enumeration enm = nameListUps.elements(); enm
0720:                        .hasMoreElements();) {
0721:                    String super OutName = ((NameListUp) enm.nextElement())
0722:                            .getMethodOutNameUp(name, descriptor);
0723:                    if (super OutName != null) {
0724:                        return super OutName;
0725:                    }
0726:                }
0727:
0728:                // Check self
0729:                Md md = getMethod(name, descriptor);
0730:                if (md != null && !Modifier.isPrivate(md.access)) {
0731:                    return md.getOutName();
0732:                } else {
0733:                    return null;
0734:                }
0735:            }
0736:
0737:            /** Get obfuscated method name from list, or null if no mapping exists. */
0738:            public String getMethodObfNameUp(String name, String descriptor)
0739:                    throws Exception {
0740:                // Check supers
0741:                for (Enumeration enm = nameListUps.elements(); enm
0742:                        .hasMoreElements();) {
0743:                    String super ObfName = ((NameListUp) enm.nextElement())
0744:                            .getMethodObfNameUp(name, descriptor);
0745:                    if (super ObfName != null) {
0746:                        return super ObfName;
0747:                    }
0748:                }
0749:
0750:                // Check self
0751:                Md md = getMethod(name, descriptor);
0752:                if (md != null && !Modifier.isPrivate(md.access)) {
0753:                    return md.getObfName();
0754:                } else {
0755:                    return null;
0756:                }
0757:            }
0758:
0759:            /** Get output field name from list, or null if no mapping exists. */
0760:            public String getFieldOutNameUp(String name) throws Exception {
0761:                // Check supers
0762:                for (Enumeration enm = nameListUps.elements(); enm
0763:                        .hasMoreElements();) {
0764:                    String super OutName = ((NameListUp) enm.nextElement())
0765:                            .getFieldOutNameUp(name);
0766:                    if (super OutName != null) {
0767:                        return super OutName;
0768:                    }
0769:                }
0770:
0771:                // Check self
0772:                Fd fd = getField(name);
0773:                if (fd != null && !Modifier.isPrivate(fd.access)) {
0774:                    return fd.getOutName();
0775:                } else {
0776:                    return null;
0777:                }
0778:            }
0779:
0780:            /** Get obfuscated field name from list, or null if no mapping exists. */
0781:            public String getFieldObfNameUp(String name) throws Exception {
0782:                // Check supers
0783:                for (Enumeration enm = nameListUps.elements(); enm
0784:                        .hasMoreElements();) {
0785:                    String super ObfName = ((NameListUp) enm.nextElement())
0786:                            .getFieldObfNameUp(name);
0787:                    if (super ObfName != null) {
0788:                        return super ObfName;
0789:                    }
0790:                }
0791:
0792:                // Check self
0793:                Fd fd = getField(name);
0794:                if (fd != null && !Modifier.isPrivate(fd.access)) {
0795:                    return fd.getObfName();
0796:                } else {
0797:                    return null;
0798:                }
0799:            }
0800:
0801:            /** Is the method reserved because of its reservation down the class hierarchy? */
0802:            public String getMethodObfNameDown(Cl caller, String name,
0803:                    String descriptor) throws Exception {
0804:                // Check ourself for an explicit 'do not obfuscate'
0805:                Md md = getMethod(name, descriptor);
0806:                if (md != null && md.isFixed()) {
0807:                    return md.getOutName();
0808:                }
0809:
0810:                // Check our supers, except for our caller (special case if we are java/lang/Object)
0811:                String theObfName = null;
0812:                if (super Class != null) {
0813:                    Cl super ClassItem = classTree.getCl(super Class);
0814:                    if (super ClassItem != caller) {
0815:                        NameListUp nl = super ClassItem != null ? (NameListUp) super ClassItem
0816:                                : getExtNameListUp(super Class);
0817:                        theObfName = nl.getMethodObfNameUp(name, descriptor);
0818:                        if (theObfName != null) {
0819:                            return theObfName;
0820:                        }
0821:                    }
0822:                    if (super Interfaces != null) {
0823:                        for (int i = 0; i < super Interfaces.length; i++) {
0824:                            Cl interfaceItem = classTree
0825:                                    .getCl(super Interfaces[i]);
0826:                            if (interfaceItem != caller) {
0827:                                NameListUp nl = interfaceItem != null ? (NameListUp) interfaceItem
0828:                                        : getExtNameListUp(super Interfaces[i]);
0829:                                theObfName = nl.getMethodObfNameUp(name,
0830:                                        descriptor);
0831:                                if (theObfName != null) {
0832:                                    return theObfName;
0833:                                }
0834:                            }
0835:                        }
0836:                    }
0837:                }
0838:
0839:                // Check our derived classes
0840:                for (Enumeration enm = nameListDowns.elements(); enm
0841:                        .hasMoreElements();) {
0842:                    theObfName = ((NameListDown) enm.nextElement())
0843:                            .getMethodObfNameDown(this , name, descriptor);
0844:                    if (theObfName != null) {
0845:                        return theObfName;
0846:                    }
0847:                }
0848:
0849:                // No reservation found
0850:                return null;
0851:            }
0852:
0853:            /** Is the field reserved because of its reservation down the class hierarchy? */
0854:            public String getFieldObfNameDown(Cl caller, String name)
0855:                    throws Exception {
0856:                // Check ourself for an explicit 'do not obfuscate'
0857:                Fd fd = getField(name);
0858:                if (fd != null && fd.isFixed()) {
0859:                    return fd.getOutName();
0860:                }
0861:
0862:                // Check our supers, except for our caller (special case if we are java/lang/Object)
0863:                String theObfName = null;
0864:                if (super Class != null) {
0865:                    Cl super ClassItem = classTree.getCl(super Class);
0866:                    if (super ClassItem != caller) {
0867:                        NameListUp nl = super ClassItem != null ? (NameListUp) super ClassItem
0868:                                : getExtNameListUp(super Class);
0869:                        theObfName = nl.getFieldObfNameUp(name);
0870:                        if (theObfName != null) {
0871:                            return theObfName;
0872:                        }
0873:                    }
0874:                    if (super Interfaces != null) {
0875:                        for (int i = 0; i < super Interfaces.length; i++) {
0876:                            Cl interfaceItem = classTree
0877:                                    .getCl(super Interfaces[i]);
0878:                            if (interfaceItem != caller) {
0879:                                NameListUp nl = interfaceItem != null ? (NameListUp) interfaceItem
0880:                                        : getExtNameListUp(super Interfaces[i]);
0881:                                theObfName = nl.getFieldObfNameUp(name);
0882:                                if (theObfName != null) {
0883:                                    return theObfName;
0884:                                }
0885:                            }
0886:                        }
0887:                    }
0888:                }
0889:
0890:                // Check our derived classes
0891:                for (Enumeration enm = nameListDowns.elements(); enm
0892:                        .hasMoreElements();) {
0893:                    theObfName = ((NameListDown) enm.nextElement())
0894:                            .getFieldObfNameDown(this , name);
0895:                    if (theObfName != null) {
0896:                        return theObfName;
0897:                    }
0898:                }
0899:
0900:                // No reservation found
0901:                return null;
0902:            }
0903:
0904:            // Construct, or retrieve from cache, the NameListUp object for an external class/interface
0905:            private static Hashtable extNameListUpCache = new Hashtable();
0906:
0907:            private NameListUp getExtNameListUp(String name) throws Exception {
0908:                NameListUp nl = (NameListUp) extNameListUpCache.get(name);
0909:                if (nl == null) {
0910:                    nl = new ExtNameListUp(name);
0911:                    extNameListUpCache.put(name, nl);
0912:                }
0913:                return nl;
0914:            }
0915:
0916:            // NameListUp for class/interface not in the database.
0917:            class ExtNameListUp implements  NameListUp {
0918:                // Class's fully qualified name
0919:                private Class extClass;
0920:                private Method[] methods = null;
0921:
0922:                // Ctor.
0923:                public ExtNameListUp(String name) throws Exception {
0924:                    extClass = Class.forName(ClassFile.translate(name));
0925:                }
0926:
0927:                // Ctor.
0928:                public ExtNameListUp(Class extClass) throws Exception {
0929:                    this .extClass = extClass;
0930:                }
0931:
0932:                // Get obfuscated method name from list, or null if no mapping exists.
0933:                public String getMethodObfNameUp(String name, String descriptor)
0934:                        throws Exception {
0935:                    return getMethodOutNameUp(name, descriptor);
0936:                }
0937:
0938:                // Get obfuscated method name from list, or null if no mapping exists.
0939:                public String getMethodOutNameUp(String name, String descriptor)
0940:                        throws Exception {
0941:                    // Get list of public/protected methods
0942:                    if (methods == null) {
0943:                        methods = getAllDeclaredMethods(extClass);
0944:                        Vector pruned = new Vector();
0945:                        for (int i = 0; i < methods.length; i++) {
0946:                            int modifiers = methods[i].getModifiers();
0947:                            if (!Modifier.isPrivate(modifiers)) {
0948:                                pruned.addElement(methods[i]);
0949:                            }
0950:                        }
0951:                        methods = new Method[pruned.size()];
0952:                        for (int i = 0; i < methods.length; i++) {
0953:                            methods[i] = (Method) pruned.elementAt(i);
0954:                        }
0955:                    }
0956:
0957:                    // Check each public/protected class method against the named one
0958:                    nextMethod: for (int i = 0; i < methods.length; i++) {
0959:                        if (name.equals(methods[i].getName())) {
0960:                            String[] paramAndReturnNames = ClassFile
0961:                                    .parseDescriptor(descriptor);
0962:                            Class[] paramTypes = methods[i].getParameterTypes();
0963:                            Class returnType = methods[i].getReturnType();
0964:                            if (paramAndReturnNames.length == paramTypes.length + 1) {
0965:                                for (int j = 0; j < paramAndReturnNames.length - 1; j++) {
0966:                                    if (!paramAndReturnNames[j]
0967:                                            .equals(paramTypes[j].getName())) {
0968:                                        continue nextMethod;
0969:                                    }
0970:                                }
0971:                                String returnName = returnType.getName();
0972:                                if (!paramAndReturnNames[paramAndReturnNames.length - 1]
0973:                                        .equals(returnName)) {
0974:                                    continue nextMethod;
0975:                                }
0976:
0977:                                // We have a match, and so the derived class method name must be made to match
0978:                                return name;
0979:                            }
0980:                        }
0981:                    }
0982:
0983:                    // Method is not present
0984:                    return null;
0985:                }
0986:
0987:                // Get obfuscated field name from list, or null if no mapping exists.
0988:                public String getFieldObfNameUp(String name) throws Exception {
0989:                    return getFieldOutNameUp(name);
0990:                }
0991:
0992:                // Get obfuscated field name from list, or null if no mapping exists.
0993:                public String getFieldOutNameUp(String name) throws Exception {
0994:                    // Use reflection to check class for field
0995:                    Field field = getAllDeclaredField(extClass, name);
0996:                    if (field != null) {
0997:                        // Field must be public or protected
0998:                        int modifiers = field.getModifiers();
0999:                        if (!Modifier.isPrivate(modifiers)) {
1000:                            return name;
1001:                        }
1002:                    }
1003:
1004:                    // Field is not present
1005:                    return null;
1006:                }
1007:
1008:                // Get all methods (from supers too) regardless of access level
1009:                private Method[] getAllDeclaredMethods(Class theClass) {
1010:                    Vector ma = new Vector();
1011:                    int length = 0;
1012:
1013:                    // Get the public methods from all supers and interfaces up the tree
1014:                    Method[] allPubMethods = theClass.getMethods();
1015:                    ma.addElement(allPubMethods);
1016:                    length += allPubMethods.length;
1017:
1018:                    // Go up the super hierarchy, getting arrays of all methods (some redundancy
1019:                    // here, but that's okay)
1020:                    while (theClass != null) {
1021:                        Method[] methods = theClass.getDeclaredMethods();
1022:                        ma.addElement(methods);
1023:                        length += methods.length;
1024:                        theClass = theClass.getSuperclass();
1025:                    }
1026:
1027:                    // Merge the arrays
1028:                    Method[] allMethods = new Method[length];
1029:                    int pos = 0;
1030:                    for (Enumeration enm = ma.elements(); enm.hasMoreElements();) {
1031:                        Method[] methods = (Method[]) enm.nextElement();
1032:                        System.arraycopy(methods, 0, allMethods, pos,
1033:                                methods.length);
1034:                        pos += methods.length;
1035:                    }
1036:                    return allMethods;
1037:                }
1038:
1039:                // Get a specified field (from supers and interfaces too) regardless of access level
1040:                private Field getAllDeclaredField(Class theClass, String name) {
1041:                    Class origClass = theClass;
1042:
1043:                    // Check for field in supers
1044:                    while (theClass != null) {
1045:                        Field field = null;
1046:                        try {
1047:                            field = theClass.getDeclaredField(name);
1048:                        } catch (Exception e) {
1049:                            field = null;
1050:                        }
1051:                        if (field != null) {
1052:                            return field;
1053:                        }
1054:                        theClass = theClass.getSuperclass();
1055:                    }
1056:
1057:                    // Check for public field in supers and interfaces 
1058:                    // (some redundancy here, but that's okay)
1059:                    try {
1060:                        return origClass.getField(name);
1061:                    } catch (Exception e) {
1062:                        return null;
1063:                    }
1064:                }
1065:            }
1066:
1067:            /** Find and add TreeItem references. */
1068:            public void findRefs(ClassFile cf) throws Exception {
1069:                // Reference all <init> and <clinit> special methods
1070:                for (Enumeration enm = mdsSpecial.elements(); enm
1071:                        .hasMoreElements();) {
1072:                    addRef((Md) enm.nextElement());
1073:                }
1074:            }
1075:
1076:            /** Remove methods and fields that are marked for trim. */
1077:            public void trimClassFile(ClassFile cf) throws Exception {
1078:                for (int i = cf.getMethodCount() - 1; i >= 0; i--) {
1079:                    MethodInfo methodInfo = cf.getMethod(i);
1080:                    Md md = getMethod(methodInfo.getName(), methodInfo
1081:                            .getDescriptor());
1082:                    if (md != null && md.isTrimmed()) {
1083:                        cf.removeMethod(i);
1084:                    }
1085:                }
1086:                for (int i = cf.getFieldCount() - 1; i >= 0; i--) {
1087:                    FieldInfo fieldInfo = cf.getField(i);
1088:                    Fd fd = getField(fieldInfo.getName());
1089:                    if (fd != null && fd.isTrimmed()) {
1090:                        cf.removeField(i);
1091:                    }
1092:                }
1093:            }
1094:
1095:            /** Walk class inheritance group taking action once only on each class. 
1096:                Must be called after setupNameListDowns() called for all classes. */
1097:            public void walkGroup(TreeAction ta) throws Exception {
1098:                Vector done = new Vector();
1099:                walkGroup(ta, this , done);
1100:            }
1101:
1102:            // Walk class inheritance group taking action once only on each class.
1103:            private void walkGroup(TreeAction ta, Cl cl, Vector done)
1104:                    throws Exception {
1105:                if (!done.contains(cl)) {
1106:                    // Take the action and mark this class as done
1107:                    ta.classAction(cl);
1108:                    done.addElement(cl);
1109:                    // Traverse super class
1110:                    Cl super Cl = classTree.getCl(super Class);
1111:                    if (super Cl != null) // ignore external to JAR
1112:                    {
1113:                        walkGroup(ta, super Cl, done);
1114:                    }
1115:                    // Traverse super interfaces
1116:                    if (super Interfaces != null) {
1117:                        for (int i = 0; i < super Interfaces.length; i++) {
1118:                            Cl interfaceItem = classTree
1119:                                    .getCl(super Interfaces[i]);
1120:                            if (interfaceItem != null) // ignore external to JAR
1121:                            {
1122:                                walkGroup(ta, interfaceItem, done);
1123:                            }
1124:                        }
1125:                    }
1126:                    // Traverse derived classes
1127:                    for (Enumeration clEnum = nameListDowns.elements(); clEnum
1128:                            .hasMoreElements();) {
1129:                        Cl subCl = (Cl) clEnum.nextElement();
1130:                        if (subCl != null) {
1131:                            walkGroup(ta, subCl, done);
1132:                        }
1133:                    }
1134:                }
1135:            }
1136:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.