KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > proguard > obfuscate > ClassOpener


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 proguard.classfile.*;
24 import proguard.classfile.constant.*;
25 import proguard.classfile.constant.visitor.ConstantVisitor;
26 import proguard.classfile.util.*;
27
28 /**
29  * This <code>ConstantVisitor</code> makes package visible classes and class
30  * members public, if they are referenced by visited references from different
31  * packages.
32  *
33  * @author Eric Lafortune
34  */

35 public class ClassOpener
36 extends SimplifiedVisitor
37 implements ConstantVisitor
38 {
39     // Implementations for ConstantVisitor.
40

41     public void visitAnyConstant(Clazz clazz, Constant constant) {}
42
43
44     public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
45     {
46         fixPackageVisibility(clazz,
47                              stringConstant.referencedClass,
48                              stringConstant.referencedMember);
49     }
50
51
52     public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
53     {
54         fixPackageVisibility(clazz,
55                              refConstant.referencedClass,
56                              refConstant.referencedMember);
57     }
58
59
60     public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
61     {
62         // Do we know the referenced class?
63
Clazz referencedClass = classConstant.referencedClass;
64         if (referencedClass != null)
65         {
66             int accessFlags = referencedClass.getAccessFlags();
67
68             // Make it public if necessary.
69
if (isNotPublic(accessFlags) &&
70                 referencedClass instanceof ProgramClass &&
71                 inDifferentPackages(clazz, referencedClass))
72             {
73                 ((ProgramClass)referencedClass).u2accessFlags =
74                     AccessUtil.replaceAccessFlags(accessFlags,
75                                                   ClassConstants.INTERNAL_ACC_PUBLIC);
76             }
77         }
78     }
79
80
81     // Small utility methods.
82

83     /**
84      * Fixes the package visibility of the given referenced class member,
85      * if necessary.
86      */

87     private void fixPackageVisibility(Clazz clazz, Clazz referencedClass, Member referencedMember)
88     {
89         // Do we know the referenced class member?
90
if (referencedMember != null)
91         {
92             int accessFlags = referencedMember.getAccessFlags();
93
94             // Make it public if necessary.
95
if (isNotPublic(accessFlags) &&
96                 referencedMember instanceof ProgramMember &&
97                 inDifferentPackages(clazz, referencedClass))
98             {
99                 ((ProgramMember)referencedMember).u2accessFlags =
100                     AccessUtil.replaceAccessFlags(accessFlags,
101                                                   clazz.extends_(referencedClass) ?
102                                                   ClassConstants.INTERNAL_ACC_PROTECTED :
103                                                   ClassConstants.INTERNAL_ACC_PUBLIC);
104             }
105         }
106     }
107
108
109     /**
110      * Returns whether the given classes are in different packages..
111      */

112     private boolean inDifferentPackages(Clazz class1, Clazz class2)
113     {
114         return !ClassUtil.internalPackageName(class1.getName()).equals(
115                 ClassUtil.internalPackageName(class2.getName()));
116     }
117
118
119     /**
120      * Returns whether the given access flags specify a non-public class
121      * or class member.
122      */

123     private boolean isNotPublic(int accessFlags)
124     {
125         return (accessFlags & ClassConstants.INTERNAL_ACC_PUBLIC) == 0;
126     }
127 }
128
Popular Tags