OSDN Git Service

0293e24d5e4e30ba96660e863f41915a225055de
[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 import org.objectweb.asm.Opcodes;
15
16 /**
17  * Managing wellknown class checking rule.
18  * 
19  * @author Haruaki TAMADA
20  * @version $Revision$ 
21  */
22 public class WellknownClassManager implements Iterable<WellknownClassJudgeRule>{
23     private List<WellknownClassJudgeRule> rules = new ArrayList<WellknownClassJudgeRule>();
24
25     public WellknownClassManager(){
26     }
27
28     public WellknownClassManager(WellknownClassManager manager){
29         rules = new ArrayList<WellknownClassJudgeRule>(manager.rules);
30     }
31
32     public void remove(WellknownClassJudgeRule rule){
33         rules.remove(rule);
34     }
35
36     public void remove(String value, MatchType matchType, MatchPartType partType){
37         remove(new WellknownClassJudgeRule(value, matchType, partType));
38     }
39
40     public void clear(){
41         rules.clear();
42     }
43
44     public synchronized Iterator<WellknownClassJudgeRule> iterator(){
45         List<WellknownClassJudgeRule> copiedRules = new ArrayList<WellknownClassJudgeRule>(rules);
46         return copiedRules.iterator();
47     }
48
49     public synchronized WellknownClassJudgeRule[] getRules(){
50         return rules.toArray(new WellknownClassJudgeRule[rules.size()]);
51     }
52
53     public void add(WellknownClassJudgeRule rule){
54         if(!rules.contains(rule)){
55             rules.add(rule);
56         }
57     }
58
59     private boolean checkSystemClass(String className){
60         FullyClassName name = new FullyClassName(className);
61         if(isMatch(name, true)){
62             return false;
63         }
64         return isMatch(name, false);
65     }
66
67     private boolean isMatch(FullyClassName name, boolean excludeFlag){
68         for(Iterator<WellknownClassJudgeRule> i = rules.iterator(); i.hasNext(); ){
69             WellknownClassJudgeRule s = i.next();
70             if(s.isExclude() == excludeFlag){
71                 boolean flag = false;
72                 String partName = name.getFullyName();
73                 if(s.getMatchPartType() == MatchPartType.CLASS_NAME){
74                     partName = name.getClassName();
75                 }
76                 else if(s.getMatchPartType() == MatchPartType.PACKAGE_NAME){
77                     partName = name.getPackageName();
78                 }
79                 switch(s.getMatchType()){
80                 case PREFIX:
81                     flag = partName.startsWith(s.getPattern());
82                     break;
83                 case SUFFIX:
84                     flag = partName.endsWith(s.getPattern());
85                     break;
86                 case EXACT:
87                     flag = partName.equals(s.getPattern());
88                     break;
89                 case NOT_MATCH:
90                     flag = !partName.equals(s.getPattern());
91                     break;
92                 }
93                 if(flag){
94                     return flag;
95                 }
96             }
97         }
98         return false;
99     }
100
101     /**
102      * check system defined methods, which are following methods.
103      * <ul>
104      *   <li><code>public static void main(String[])</code></li>
105      *   <li><code>static void &lt;clinit&gt;(void)</code>(static initializer)</li>
106      *   <li><code>void &lt;init&gt;</code>(constructor)</li>
107      * </ul>
108      */
109     private boolean checkSystemMethod(int access, String methodName, String signature){
110         if(methodName.equals("main")){
111             return signature.equals("([Ljava/lang/String;)V")
112                 && checkAccess(access, Opcodes.ACC_PUBLIC);
113         }
114         else if(methodName.equals("<clinit>")){
115             return signature.equals("()V")
116                 && checkAccess(access, Opcodes.ACC_STATIC);
117         }
118         else if(methodName.equals("<init>")){
119             return !checkAccess(access, Opcodes.ACC_STATIC);
120         }
121         return false;
122     }
123
124     /**
125      * check system defined field, which is following field.
126      * <ul>
127      *   <code>static final long serialVersionUID</code>
128      * </ul>
129      */
130     private boolean checkSystemField(int access, String fieldName, String signature){
131         if(fieldName.equals("serialVersionUID")){
132             return checkAccess(access, Opcodes.ACC_STATIC) &&
133                 checkAccess(access, Opcodes.ACC_FINAL) &&
134                 signature.equals("J");
135         }
136
137         return false;
138     }
139
140     public boolean isWellKnownClass(String className){
141         return checkSystemClass(className);
142     }
143
144     public boolean isSystemMethod(int access, String methodName, String signature){
145         return checkSystemMethod(access, methodName, signature);
146     }
147
148     public boolean isSystemField(int access, String fieldName, String signature){
149         return checkSystemField(access, fieldName, signature);
150     }
151
152     private boolean checkAccess(int access, int code){
153         return (access & code) == code;
154     }
155 }