KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > aspectwerkz > expression > regexp > TypePattern


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
3  */

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

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

26   protected transient com.tc.jrexx.regex.Pattern m_typeNamePattern;
27
28   /**
29    * The pattern as a string.
30    */

31   protected String JavaDoc m_pattern;
32
33   /**
34    * The subtype pattern type.
35    */

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

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

56   public boolean matches(String JavaDoc typeName) {
57     // regular match
58
if (m_typeNamePattern.contains(typeName)) {
59       return true;
60     }
61
62     // fallback on subclassing proxy match and Cglib extension
63
int awProxySuffixStart1 = typeName.indexOf(ProxySubclassingStrategy.PROXY_SUFFIX);
64     int awProxySuffixStart2 = typeName.indexOf(ProxyDelegationStrategy.PROXY_SUFFIX);
65     if (awProxySuffixStart1 > 0) {
66       typeName = typeName.substring(0, awProxySuffixStart1);
67     } else if (awProxySuffixStart2 > 0) {
68       typeName = typeName.substring(0, awProxySuffixStart2);
69     } else {
70       int cglibFastClassSuffixStarg = typeName.indexOf("$$FastClassByCGLIB$$");
71       if (cglibFastClassSuffixStarg > 0) {
72         // always filter away cglib fast class classes
73
return false;
74       }
75       int cglibEnhancerSuffixStart = typeName.indexOf("$$EnhancerByCGLIB$$");
76       if (cglibEnhancerSuffixStart > 0) {
77         typeName = typeName.substring(0, cglibEnhancerSuffixStart);
78       }
79     }
80     if (typeName == null) {
81       return false;
82     }
83     if (typeName.equals("")) {
84       return false;
85     }
86     return m_typeNamePattern.contains(typeName);
87   }
88
89   /**
90    * Matches a type.
91    *
92    * @param classInfo the info of the class
93    * @return
94    */

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

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

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

166   public SubtypePatternType getSubtypePatternType() {
167     return m_subtypePatternType;
168   }
169
170   /**
171    * Checks if the pattern matches all types.
172    *
173    * @return boolean
174    */

175   public boolean isEagerWildCard() {
176     return m_pattern.equals(EAGER_WILDCARD);
177   }
178
179   /**
180    * Returns the pattern as a string.
181    *
182    * @return the pattern
183    */

184   public String JavaDoc getPattern() {
185     return m_pattern;
186   }
187
188   /**
189    * Escapes the type pattern.
190    *
191    * @param pattern the method pattern
192    */

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

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