|
|||||||||||||||||||
Source file | Conditionals | Statements | Methods | TOTAL | |||||||||||||||
MethodMatcher.java | 100% | 100% | 100% | 100% |
|
1 | // Copyright 2004, 2005 The Apache Software Foundation | |
2 | // | |
3 | // Licensed under the Apache License, Version 2.0 (the "License"); | |
4 | // you may not use this file except in compliance with the License. | |
5 | // You may obtain a copy of the License at | |
6 | // | |
7 | // http://www.apache.org/licenses/LICENSE-2.0 | |
8 | // | |
9 | // Unless required by applicable law or agreed to in writing, software | |
10 | // distributed under the License is distributed on an "AS IS" BASIS, | |
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
12 | // See the License for the specific language governing permissions and | |
13 | // limitations under the License. | |
14 | ||
15 | package org.apache.hivemind.methodmatch; | |
16 | ||
17 | import java.util.ArrayList; | |
18 | import java.util.Iterator; | |
19 | import java.util.List; | |
20 | ||
21 | import org.apache.hivemind.ApplicationRuntimeException; | |
22 | import org.apache.hivemind.HiveMind; | |
23 | import org.apache.hivemind.Location; | |
24 | import org.apache.hivemind.service.MethodSignature; | |
25 | ||
26 | /** | |
27 | * A utility class used for matching a {@link org.apache.hivemind.service.MethodSignature} against a | |
28 | * method pattern (this is primarily used by {@link org.apache.hivemind.ServiceInterceptorFactory | |
29 | * interceptor factories}). A method pattern consists of a <em>name pattern</em> and an optional | |
30 | * <em>parameters pattern</em>. | |
31 | * <p> | |
32 | * The name pattern matches against the method name, and can be one of the following: | |
33 | * <ul> | |
34 | * <li>A single name - which requires an exact match. Example: <code>perform</code> | |
35 | * <li>A name suffix, indicated with a leading '*'. Example: <code>*form</code> | |
36 | * <li>A name prefix, indicated with a trailing '*'. Example: <code>per*</code> | |
37 | * <li>A name substring, indicated with leading and trailing '*'s. Example: <code>*erfo*</code>. | |
38 | * <li>A match any, indicated with a single '*'. Example: <code>*</code> | |
39 | * </ul> | |
40 | * <p> | |
41 | * The parameters pattern follows the name pattern and is optional. It is used to check the number | |
42 | * of parameters, or their types. When the parameters pattern is omitted, then the number and types | |
43 | * of parameters are not considred when matching methods. | |
44 | * <p> | |
45 | * The parameters pattern, when present, is contained within open and closed parenthis after the | |
46 | * method pattern. Inside the parenthesis may be a number, indicating the exact number of method | |
47 | * parameters to match against. Alternately, a comma-seperated list of Java types is used, which | |
48 | * matches against a method that takes the exact set of parameters. Examples: | |
49 | * <ul> | |
50 | * <li><code>perform()</code>-- method with no parameters | |
51 | * <li><code>perform(2)</code>-- method with two parameters | |
52 | * <li><code>perform(java.util.List, int)</code>- method taking a List and an int parameter | |
53 | * </ul> | |
54 | * | |
55 | * @author Howard Lewis Ship | |
56 | */ | |
57 | public class MethodMatcher | |
58 | { | |
59 | private class StoredPattern | |
60 | { | |
61 | String _methodPattern; | |
62 | ||
63 | MethodFilter _filter; | |
64 | ||
65 | Object _patternValue; | |
66 | ||
67 | 9 | StoredPattern(String pattern, Object value) |
68 | { | |
69 | 9 | _methodPattern = pattern; |
70 | 9 | _patternValue = value; |
71 | } | |
72 | ||
73 | 11 | boolean match(MethodSignature sig) |
74 | { | |
75 | 11 | if (_filter == null) |
76 | { | |
77 | ||
78 | 8 | try |
79 | { | |
80 | 8 | _filter = parseMethodPattern(_methodPattern); |
81 | } | |
82 | catch (RuntimeException ex) | |
83 | { | |
84 | 2 | Location l = HiveMind.findLocation(new Object[] |
85 | { _patternValue, ex }); | |
86 | ||
87 | 2 | if (l == null) |
88 | 1 | throw ex; |
89 | ||
90 | 1 | throw new ApplicationRuntimeException(MethodMatchMessages.exceptionAtLocation( |
91 | l, | |
92 | ex), ex); | |
93 | } | |
94 | } | |
95 | ||
96 | 9 | return _filter.matchMethod(sig); |
97 | } | |
98 | } | |
99 | ||
100 | private MethodPatternParser _parser = new MethodPatternParser(); | |
101 | ||
102 | private List _methodInfos; | |
103 | ||
104 | private Object _defaultValue; | |
105 | ||
106 | /** | |
107 | * Constructor that takes a default value returned when no stored method pattern matches the | |
108 | * input to {@link #get(MethodSignature)}. | |
109 | * | |
110 | * @since 1.1 | |
111 | */ | |
112 | 9 | public MethodMatcher(Object defaultValue) |
113 | { | |
114 | 9 | _defaultValue = defaultValue; |
115 | } | |
116 | ||
117 | 8 | public MethodMatcher() |
118 | { | |
119 | 8 | this(null); |
120 | } | |
121 | ||
122 | 8 | private MethodFilter parseMethodPattern(String pattern) |
123 | { | |
124 | 8 | return _parser.parseMethodPattern(pattern); |
125 | } | |
126 | ||
127 | /** | |
128 | * Stores a pattern and an associated value. Values can later be accessed via | |
129 | * {@link #get(MethodSignature)}. | |
130 | * | |
131 | * @param methodPattern | |
132 | * a pattern that is used to recognize methods | |
133 | * @param patternValue | |
134 | * a value associated with the pattern | |
135 | */ | |
136 | 9 | public synchronized void put(String methodPattern, Object patternValue) |
137 | { | |
138 | 9 | if (_methodInfos == null) |
139 | 7 | _methodInfos = new ArrayList(); |
140 | ||
141 | 9 | StoredPattern sp = new StoredPattern(methodPattern, patternValue); |
142 | ||
143 | 9 | _methodInfos.add(sp); |
144 | } | |
145 | ||
146 | /** | |
147 | * Returns a pattern value prevoiusly stored via {@link #put(String, Object)}. Iterates over | |
148 | * the patterns stored, in the order in which they were stored, until a match is found. | |
149 | * | |
150 | * @param sig | |
151 | * the MethodSignature to find a matching pattern for | |
152 | * @return the pattern value for the matching pattern, or the default value if not found (the | |
153 | * default value may be set in the constructor) | |
154 | */ | |
155 | 11 | public synchronized Object get(MethodSignature sig) |
156 | { | |
157 | 11 | if (_methodInfos == null) |
158 | 2 | return _defaultValue; |
159 | ||
160 | 9 | Iterator i = _methodInfos.iterator(); |
161 | 9 | while (i.hasNext()) |
162 | { | |
163 | 11 | StoredPattern sp = (StoredPattern) i.next(); |
164 | ||
165 | 11 | if (sp.match(sig)) |
166 | 4 | return sp._patternValue; |
167 | } | |
168 | ||
169 | // Not found. | |
170 | ||
171 | 3 | return _defaultValue; |
172 | } | |
173 | } |
|