KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > codehaus > aspectwerkz > expression > regexp > TypePattern


1 /**************************************************************************************
2  * Copyright (c) Jonas BonŽr, Alexandre Vasseur. All rights reserved. *
3  * http://aspectwerkz.codehaus.org *
4  * ---------------------------------------------------------------------------------- *
5  * The software in this package is published under the terms of the LGPL license *
6  * a copy of which has been included with this distribution in the license.txt file. *
7  **************************************************************************************/

8 package org.codehaus.aspectwerkz.expression.regexp;
9
10 import org.codehaus.aspectwerkz.expression.ExpressionException;
11 import org.codehaus.aspectwerkz.expression.SubtypePatternType;
12 import org.codehaus.aspectwerkz.util.Strings;
13 import org.codehaus.aspectwerkz.reflect.ClassInfo;
14 import org.codehaus.aspectwerkz.proxy.Proxy;
15
16 import java.io.ObjectInputStream JavaDoc;
17
18 /**
19  * Implements the regular expression pattern matcher for types.
20  *
21  * @author <a HREF="mailto:jboner@codehaus.org">Jonas BonŽr </a>
22  */

23 public class TypePattern extends Pattern {
24
25     /**
26      * The fully qualified type name.
27      */

28     protected transient com.karneim.util.collection.regex.Pattern m_typeNamePattern;
29
30     /**
31      * The pattern as a string.
32      */

33     protected String JavaDoc m_pattern;
34
35     /**
36      * The subtype pattern type.
37      */

38     private SubtypePatternType m_subtypePatternType;
39
40     /**
41      * Private constructor.
42      *
43      * @param pattern the pattern
44      * @param subtypePatternType the subtype pattern type
45      */

46     TypePattern(final String JavaDoc pattern, final SubtypePatternType subtypePatternType) {
47         m_pattern = pattern;
48         m_subtypePatternType = subtypePatternType;
49         escape(m_pattern);
50     }
51
52     /**
53      * Matches a type name.
54      *
55      * @param typeName the name of the type
56      * @return true if we have a matche
57      */

58     public boolean matches(String JavaDoc typeName) {
59         int awProxySuffixStart = typeName.indexOf(Proxy.PROXY_SUFFIX_START);
60         if (awProxySuffixStart > 0) {
61             typeName = typeName.substring(0, awProxySuffixStart);
62         } else {
63             int cglibFastClassSuffixStarg = typeName.indexOf("$$FastClassByCGLIB$$");
64             if (cglibFastClassSuffixStarg > 0) {
65                 // always filter away cglib fast class classes
66
return false;
67             }
68             int cglibEnhancerSuffixStart = typeName.indexOf("$$EnhancerByCGLIB$$");
69             if (cglibEnhancerSuffixStart > 0) {
70                 typeName = typeName.substring(0, cglibEnhancerSuffixStart);
71             }
72         }
73         if (typeName == null) {
74             return false;
75         }
76         if (typeName.equals("")) {
77             return false;
78         }
79         return m_typeNamePattern.contains(typeName);
80     }
81
82     /**
83      * Matches a type.
84      *
85      * @param classInfo the info of the class
86      * @return
87      */

88     public boolean matchType(final ClassInfo classInfo) {
89         SubtypePatternType type = getSubtypePatternType();
90         if (type.equals(SubtypePatternType.MATCH_ON_ALL_METHODS)) {
91             return matchSuperClasses(classInfo);
92         } else if (type.equals(SubtypePatternType.MATCH_ON_BASE_TYPE_METHODS_ONLY)) {
93             // TODO: matching on methods ONLY in base type needs to be completed
94
// TODO: needs to work together with the method and field matching somehow
95
return matchSuperClasses(classInfo);
96         } else {
97             return matches(classInfo.getName());
98         }
99     }
100
101     /**
102      * Tries to finds a parse at some superclass in the hierarchy. <p/>Only checks for a class parse to allow early
103      * filtering. <p/>Recursive.
104      *
105      * @param classInfo the class info
106      * @return boolean
107      */

108     public boolean matchSuperClasses(final ClassInfo classInfo) {
109         if ((classInfo == null)) {
110             return false;
111         }
112
113         // parse the class/super class
114
if (matches(classInfo.getName())) {
115             return true;
116         } else {
117             // parse the interfaces for the class
118
if (matchInterfaces(classInfo.getInterfaces(), classInfo)) {
119                 return true;
120             }
121
122             // no parse; getClass the next superclass
123
return matchSuperClasses(classInfo.getSuperclass());
124         }
125     }
126
127     /**
128      * Tries to finds a parse at some interface in the hierarchy. <p/>Only checks for a class parse to allow early
129      * filtering. <p/>Recursive.
130      *
131      * @param interfaces the interfaces
132      * @param classInfo the class info
133      * @return boolean
134      */

135     public boolean matchInterfaces(final ClassInfo[] interfaces, final ClassInfo classInfo) {
136         if ((interfaces.length == 0) || (classInfo == null)) {
137             return false;
138         }
139         for (int i = 0; i < interfaces.length; i++) {
140             ClassInfo anInterface = interfaces[i];
141             if (matches(anInterface.getName())) {
142                 return true;
143             } else {
144                 if (matchInterfaces(anInterface.getInterfaces(), classInfo)) {
145                     return true;
146                 } else {
147                     continue;
148                 }
149             }
150         }
151         return false;
152     }
153
154     /**
155      * Returns the subtype pattern type
156      *
157      * @return boolean
158      */

159     public SubtypePatternType getSubtypePatternType() {
160         return m_subtypePatternType;
161     }
162
163     /**
164      * Checks if the pattern matches all types.
165      *
166      * @return boolean
167      */

168     public boolean isEagerWildCard() {
169         return m_pattern.equals(EAGER_WILDCARD);
170     }
171
172     /**
173      * Returns the pattern as a string.
174      *
175      * @return the pattern
176      */

177     public String JavaDoc getPattern() {
178         return m_pattern;
179     }
180
181     /**
182      * Escapes the type pattern.
183      *
184      * @param pattern the method pattern
185      */

186     protected void escape(final String JavaDoc pattern) {
187         String JavaDoc typeName = pattern;
188         if (ABBREVIATIONS.containsKey(pattern)) {
189             typeName = (String JavaDoc) ABBREVIATIONS.get(pattern);
190         }
191         try {
192             if (typeName.equals(REGULAR_WILDCARD) || typeName.equals(EAGER_WILDCARD)) {
193                 typeName = "[a-zA-Z0-9_$.\\[\\]]+";
194             } else {
195                 // CAUTION: order matters
196
typeName = Strings.replaceSubString(typeName, "[", "\\[");
197                 typeName = Strings.replaceSubString(typeName, "]", "\\]");
198                 typeName = Strings.replaceSubString(typeName, "..", "[a-zA-Z0-9_$.]+");
199                 typeName = Strings.replaceSubString(typeName, ".", "\\.");
200                 typeName = Strings.replaceSubString(typeName, "*", "[a-zA-Z0-9_$\\[\\]]*");
201             }
202             m_typeNamePattern = new com.karneim.util.collection.regex.Pattern(typeName);
203         } catch (Throwable JavaDoc e) {
204             throw new ExpressionException("type pattern is not well formed: " + pattern, e);
205         }
206     }
207
208     /**
209      * Provides custom deserialization.
210      *
211      * @param stream the object input stream containing the serialized object
212      * @throws Exception in case of failure
213      */

214     private void readObject(final ObjectInputStream JavaDoc stream) throws Exception JavaDoc {
215         ObjectInputStream.GetField JavaDoc fields = stream.readFields();
216         m_pattern = (String JavaDoc) fields.get("m_pattern", null);
217         escape(m_pattern);
218     }
219
220     public int hashCode() {
221         int result = 17;
222         result = (37 * result) + hashCodeOrZeroIfNull(m_pattern);
223         result = (37 * result) + hashCodeOrZeroIfNull(m_typeNamePattern);
224         return result;
225     }
226
227     protected static int hashCodeOrZeroIfNull(final Object JavaDoc o) {
228         if (null == o) {
229             return 19;
230         }
231         return o.hashCode();
232     }
233
234     public boolean equals(final Object JavaDoc o) {
235         if (this == o) {
236             return true;
237         }
238         if (!(o instanceof TypePattern)) {
239             return false;
240         }
241         final TypePattern obj = (TypePattern) o;
242         return areEqualsOrBothNull(obj.m_pattern, this.m_pattern)
243                && areEqualsOrBothNull(obj.m_typeNamePattern, this.m_typeNamePattern);
244     }
245
246     protected static boolean areEqualsOrBothNull(final Object JavaDoc o1, final Object JavaDoc o2) {
247         if (null == o1) {
248             return (null == o2);
249         }
250         return o1.equals(o2);
251     }
252 }
Popular Tags