View Javadoc

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  
14  import java.io.ObjectInputStream;
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       * The fully qualified type name.
24       */
25      protected transient com.karneim.util.collection.regex.Pattern m_typeNamePattern;
26  
27      /***
28       * The pattern as a string.
29       */
30      protected String m_pattern;
31  
32      /***
33       * The subtype pattern type.
34       */
35      private SubtypePatternType m_subtypePatternType;
36  
37      /***
38       * Private constructor.
39       * 
40       * @param pattern the pattern
41       * @param subtypePatternType the subtype pattern type
42       */
43      TypePattern(final String pattern, final SubtypePatternType subtypePatternType) {
44          m_pattern = pattern;
45          m_subtypePatternType = subtypePatternType;
46          escape(m_pattern);
47      }
48  
49      /***
50       * Matches a type name.
51       * 
52       * @param typeName the name of the type
53       * @return true if we have a matche
54       */
55      public boolean matches(final String typeName) {
56          if (typeName == null) {
57              throw new IllegalArgumentException("type name can not be null");
58          }
59          if (typeName.equals("")) {
60              return false;
61          }
62          return m_typeNamePattern.contains(typeName);
63      }
64  
65      /***
66       * Returns the subtype pattern type
67       * 
68       * @return boolean
69       */
70      public SubtypePatternType getSubtypePatternType() {
71          return m_subtypePatternType;
72      }
73  
74      /***
75       * Checks if the pattern matches all types.
76       * 
77       * @return boolean
78       */
79      public boolean isEagerWildCard() {
80          return m_pattern.equals(EAGER_WILDCARD);
81      }
82  
83      /***
84       * Returns the pattern as a string.
85       * 
86       * @return the pattern
87       */
88      public String getPattern() {
89          return m_pattern;
90      }
91  
92      /***
93       * Escapes the type pattern.
94       * 
95       * @param pattern the method pattern
96       */
97      protected void escape(final String pattern) {
98          String typeName = pattern;
99          if (ABBREVIATIONS.containsKey(pattern)) {
100             typeName = (String) ABBREVIATIONS.get(pattern);
101         }
102         try {
103             if (typeName.equals(REGULAR_WILDCARD) || typeName.equals(EAGER_WILDCARD)) {
104                 typeName = "[a-zA-Z0-9_$.//[//]]+";
105             } else {
106                 // CAUTION: order matters
107                 typeName = Strings.replaceSubString(typeName, "[", "//[");
108                 typeName = Strings.replaceSubString(typeName, "]", "//]");
109                 typeName = Strings.replaceSubString(typeName, "..", "[a-zA-Z0-9_$.]+");
110                 typeName = Strings.replaceSubString(typeName, ".", "//.");
111                 typeName = Strings.replaceSubString(typeName, "*", "[a-zA-Z0-9_$//[//]]*");
112             }
113             m_typeNamePattern = new com.karneim.util.collection.regex.Pattern(typeName);
114         } catch (Throwable e) {
115             throw new ExpressionException("type pattern is not well formed: " + pattern, e);
116         }
117     }
118 
119     /***
120      * Provides custom deserialization.
121      * 
122      * @param stream the object input stream containing the serialized object
123      * @throws Exception in case of failure
124      */
125     private void readObject(final ObjectInputStream stream) throws Exception {
126         ObjectInputStream.GetField fields = stream.readFields();
127         m_pattern = (String) fields.get("m_pattern", null);
128         escape(m_pattern);
129     }
130 
131     public int hashCode() {
132         int result = 17;
133         result = (37 * result) + hashCodeOrZeroIfNull(m_pattern);
134         result = (37 * result) + hashCodeOrZeroIfNull(m_typeNamePattern);
135         return result;
136     }
137 
138     protected static int hashCodeOrZeroIfNull(final Object o) {
139         if (null == o) {
140             return 19;
141         }
142         return o.hashCode();
143     }
144 
145     public boolean equals(final Object o) {
146         if (this == o) {
147             return true;
148         }
149         if (!(o instanceof TypePattern)) {
150             return false;
151         }
152         final TypePattern obj = (TypePattern) o;
153         return areEqualsOrBothNull(obj.m_pattern, this.m_pattern)
154             && areEqualsOrBothNull(obj.m_typeNamePattern, this.m_typeNamePattern);
155     }
156 
157     protected static boolean areEqualsOrBothNull(final Object o1, final Object o2) {
158         if (null == o1) {
159             return (null == o2);
160         }
161         return o1.equals(o2);
162     }
163 }