OSDN Git Service

c9f297c9133ce2bb9b9741fbb16e64a6bb306fb0
[stigmata/stigmata.git] / src / main / java / jp / sourceforge / stigmata / utils / WellknownClassManager.java
1 package jp.sourceforge.stigmata.utils;
2
3 /* 
4  * $Id$
5  */
6
7 import java.util.ArrayList;
8 import java.util.Iterator;
9 import java.util.List;
10
11 import jp.sourceforge.stigmata.utils.WellknownClassJudgeRule.MatchPartType;
12 import jp.sourceforge.stigmata.utils.WellknownClassJudgeRule.MatchType;
13
14 /**
15  * Managing wellknown class checking rule.
16  * 
17  * @author Haruaki TAMADA
18  * @version $Revision$ 
19  */
20 public class WellknownClassManager implements Iterable<WellknownClassJudgeRule>{
21     private List<WellknownClassJudgeRule> rules = new ArrayList<WellknownClassJudgeRule>();
22
23     /**
24      * public field/method flag defined in JVM specification.
25      */
26     private static final int OPCODE_ACC_PUBLIC = 1;
27     /**
28      * private field/method flag defined in JVM specification.
29      */
30     private static final int OPCODE_ACC_PRIVATE = 2;
31     /**
32      * protected field/method flag defined in JVM specification.
33      */
34     private static final int OPCODE_ACC_PROTECTED = 4;
35     /**
36      * static field/method flag defined in JVM specification.
37      */
38     private static final int OPCODE_ACC_STATIC = 8;
39     /**
40      * final field/method flag defined in JVM specification.
41      */
42     private static final int OPCODE_ACC_FINAL = 16;
43
44     /**
45      * default constructor.
46      */
47     public WellknownClassManager(){
48     }
49
50     /**
51      * constructor with parent WellknownClassManager.
52      */
53     public WellknownClassManager(WellknownClassManager manager){
54         rules = new ArrayList<WellknownClassJudgeRule>(manager.rules);
55     }
56
57     public void remove(WellknownClassJudgeRule rule){
58         rules.remove(rule);
59     }
60
61     public void remove(String value, MatchType matchType, MatchPartType partType){
62         remove(new WellknownClassJudgeRule(value, matchType, partType));
63     }
64
65     public void clear(){
66         rules.clear();
67     }
68
69     @Override
70     public synchronized Iterator<WellknownClassJudgeRule> iterator(){
71         List<WellknownClassJudgeRule> copiedRules = new ArrayList<WellknownClassJudgeRule>(rules);
72         return copiedRules.iterator();
73     }
74
75     public synchronized WellknownClassJudgeRule[] getRules(){
76         return rules.toArray(new WellknownClassJudgeRule[rules.size()]);
77     }
78
79     public void add(WellknownClassJudgeRule rule){
80         if(!rules.contains(rule)){
81             rules.add(rule);
82         }
83     }
84
85     private boolean checkSystemClass(String className){
86         FullyClassName name = new FullyClassName(className);
87         if(isMatch(name, true)){
88             return false;
89         }
90         return isMatch(name, false);
91     }
92
93     private boolean isMatch(FullyClassName name, boolean excludeFlag){
94         for(Iterator<WellknownClassJudgeRule> i = rules.iterator(); i.hasNext(); ){
95             WellknownClassJudgeRule s = i.next();
96             if(s.isExclude() == excludeFlag){
97                 boolean flag = false;
98                 String partName = name.getFullyName();
99                 if(s.getMatchPartType() == MatchPartType.CLASS_NAME){
100                     partName = name.getClassName();
101                 }
102                 else if(s.getMatchPartType() == MatchPartType.PACKAGE_NAME){
103                     partName = name.getPackageName();
104                 }
105                 switch(s.getMatchType()){
106                 case PREFIX:
107                     flag = partName.startsWith(s.getPattern());
108                     break;
109                 case SUFFIX:
110                     flag = partName.endsWith(s.getPattern());
111                     break;
112                 case EXACT:
113                     flag = partName.equals(s.getPattern());
114                     break;
115                 case NOT_MATCH:
116                     flag = !partName.equals(s.getPattern());
117                     break;
118                 }
119                 if(flag){
120                     return flag;
121                 }
122             }
123         }
124         return false;
125     }
126
127     /**
128      * check system defined methods, which are following methods.
129      * <ul>
130      *   <li><code>public static void main(String[])</code></li>
131      *   <li><code>static void &lt;clinit&gt;(void)</code>(static initializer)</li>
132      *   <li><code>void &lt;init&gt;</code>(constructor)</li>
133      * </ul>
134      */
135     private boolean checkSystemMethod(int access, String methodName, String signature){
136         if(methodName.equals("main")){
137             return signature.equals("([Ljava/lang/String;)V")
138                 && checkAccess(access, OPCODE_ACC_PUBLIC);
139         }
140         else if(methodName.equals("<clinit>")){
141             return signature.equals("()V")
142                 && checkAccess(access, OPCODE_ACC_STATIC);
143         }
144         else if(methodName.equals("<init>")){
145             return !checkAccess(access, OPCODE_ACC_STATIC);
146         }
147         return false;
148     }
149
150     /**
151      * check system defined field, which is following field.
152      * <ul>
153      *   <code>static final long serialVersionUID</code>
154      * </ul>
155      */
156     private boolean checkSystemField(int access, String fieldName, String signature){
157         if(fieldName.equals("serialVersionUID")){
158             return checkAccess(access, OPCODE_ACC_STATIC) &&
159                 checkAccess(access, OPCODE_ACC_FINAL) &&
160                 signature.equals("J");
161         }
162
163         return false;
164     }
165
166     public boolean isWellKnownClass(String className){
167         return checkSystemClass(className);
168     }
169
170     public boolean isSystemMethod(int access, String methodName, String signature){
171         return checkSystemMethod(access, methodName, signature);
172     }
173
174     public boolean isSystemField(int access, String fieldName, String signature){
175         return checkSystemField(access, fieldName, signature);
176     }
177
178     private boolean checkAccess(int access, int code){
179         return (access & code) == code;
180     }
181 }