KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > alt > jiapi > InstrumentationDescriptor


1 /*
2  * Copyright (C) 2001 Mika Riekkinen, Joni Suominen
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  */

18
19 package alt.jiapi;
20
21 import java.util.Collections JavaDoc;
22 import java.util.ArrayList JavaDoc;
23 import java.util.Iterator JavaDoc;
24 import java.util.List JavaDoc;
25 import java.util.Set JavaDoc;
26 import java.util.TreeSet JavaDoc;
27
28 import org.apache.log4j.Category;
29
30 /**
31  * This class holds information needed by the instrumentation process.
32  * It has a List of Instrumentations. The Instrumentations define
33  * the instrumentation function.<p>
34  *
35  * InstrumentationDescriptor holds those Instrumentations which
36  * use the same Rules. Rules define which classes is to be instrumented.<p>
37  *
38  * @see Instrumentation
39  *
40  * @author Mika Riekkinen
41  * @author Joni Suominen
42  * @version $Revision: 1.15 $ $Date: 2004/08/11 10:12:31 $
43  */

44 public class InstrumentationDescriptor {
45     private static Category log = Runtime.getLogCategory(InstrumentationDescriptor.class);
46
47     /**
48      * For debugging inclusion/exclusion
49      */

50     private boolean debugLoader = false;
51
52     /**
53      * A list of Instrumentations.
54      */

55     private List JavaDoc instrumentors = Collections.synchronizedList(new ArrayList JavaDoc());
56
57     /**
58      * Inclusion rules in significance order,
59      */

60     private Set JavaDoc inclusionRules = new TreeSet JavaDoc(Collections.reverseOrder());
61
62     /**
63      * Exclusion rules in significance order,
64      */

65     private Set JavaDoc exclusionRules = new TreeSet JavaDoc(Collections.reverseOrder());
66     
67     public InstrumentationDescriptor() {
68         // Empty constructor. Check null-pointer-check on
69
// the other constructor.
70
}
71
72     /**
73      * Adds a new chain.
74      *
75      * @param i Instrumentor that is used in instrumenting
76      * @param patch Patch, which is associated with the Instrumentor given
77      */

78     public void addInstrumentor(Instrumentor instrumentor) {
79         instrumentors.add(instrumentor);
80     }
81
82     /**
83      * Gets all the Instrumentations.
84      *
85      * @return An ordered List of Instrumentations.
86      */

87     public List JavaDoc getInstrumentors() {
88         return instrumentors;
89     }
90
91     /**
92      * Adds a rule to this descriptor. Each Instrumentor - Patch
93      * pair is joined with this rule. When instrumenting, if inclusion
94      * rule matches a class/method that is loaded by the ClassLoader,
95      * Instrumentors, that are registered to this descriptor by
96      * <b>addBinding(Instrumentor, Patch)</b> are called with
97      * bytecode, that reflects the method. Instrumentor is then
98      * supposed to modify that class somehow.<p>
99      * Format of the rule is the same, as fully qualified Java
100      * package/class/method names. For example, following are valid
101      * rules: <p>
102      * <ul>
103      * <li>my.package.*
104      * <li>my.package.SomeClass
105      * <li>my.*.SomeClass
106      * <li>my.package.SomeClass.someMethod()V
107      * </ul>
108      *
109      * @param rule A Inclusion rule, that is to be added to this descriptor
110      * @exception JiapiException thrown if there's a syntax error in rule
111      */

112     public void addInclusionRule(String JavaDoc rule) throws JiapiException {
113         inclusionRules.add(new Rule(rule));
114     }
115
116     /**
117      * Gets the inclusion rules of this descriptor.
118      * @return a Set of inclusion rules
119      */

120     public Set JavaDoc getInclusionsRules() {
121         return inclusionRules;
122     }
123
124     /**
125      * Adds an exclusion rule to this descriptor. When choosing whether
126      * a class/method is to be insturmented, if exclusion rule matches,
127      * that class/method will be skipped from instrumentation.<p>
128      * In general Exclusion rules are more powerful than inclusion
129      * rules. That is, if for some reason two similar rules are assigned
130      * to both exclusion and inclusion rules, exclusion rule will win.
131      *
132      * @param rule A Exclusion rule, that is to be added to this descriptor
133      * @exception JiapiException thrown if there's a syntax error in rule
134      */

135     public void addExclusionRule(String JavaDoc rule) throws JiapiException {
136         exclusionRules.add(new Rule(rule));
137     }
138
139     /**
140      * Gets the inclusion rules of this descriptor.
141      * @return a Set of inclusion rules
142      */

143     public Set JavaDoc getExclusionsRules() {
144         return exclusionRules;
145     }
146
147     /**
148      * Check whether the given className matches any of given rules.
149      * Excplicit exclusion rules win if they are more significant
150      * than inclusion rules.
151      *
152      * @param className a class name
153      */

154     public boolean match(String JavaDoc className) {
155         log.debug("Matching rules to " + className);
156
157         Rule exclusionRule = null;
158         Rule inclusionRule = null;
159
160         // Then the most significant inclusion rule:
161
for (Iterator JavaDoc i = inclusionRules.iterator(); i.hasNext(); ) {
162             Rule rule = (Rule) i.next();
163             if (rule.match(className)) {
164                 //log.debug("Including: " + className + " cause: " + rule);
165

166                 inclusionRule = rule;
167                 break;
168             }
169         }
170
171         // 1. If the class has not been explicitely included, it will
172
// not match this descriptor.
173
if (inclusionRule == null) {
174             log.debug("Excluding: " + className + " cause: no match");
175
176             return false;
177         }
178
179         // Find first the most significant exclusion rule:
180
for (Iterator JavaDoc i = exclusionRules.iterator(); i.hasNext(); ) {
181             Rule rule = (Rule) i.next();
182             if (rule.match(className)) {
183                 exclusionRule = rule;
184                 break;
185             }
186         }
187
188         // 2. The class matches inclusion rule. If it doesn't match
189
// any exclusion rule, it will match this descriptor.
190
if (exclusionRule == null) {
191             log.debug("Including: " + className + " cause: " + inclusionRule +
192                       ", no exclusion rule");
193
194             return true;
195         }
196
197         // 3. The class matches both inclusion rule and exclusion rule.
198
// If inclusion is more significant than exclusion rule, the class
199
// will match this descriptor.
200
if (inclusionRule.isMoreSignificant(exclusionRule)) {
201             log.debug("Including: " + className + " cause:\n include " +
202                       inclusionRule + " is more significant than " +
203                       exclusionRule);
204
205             return true;
206         }
207         else {
208             log.debug("Excluding: " + className + " cause:\n excluding " +
209                       exclusionRule + " is more significant than " +
210                       inclusionRule);
211
212             return false;
213         }
214
215     }
216
217     public String JavaDoc toString() {
218         return inclusionRules.toString() + ", " + exclusionRules.toString();
219     }
220 }
221
222
Popular Tags