001: /*
002: * Copyright 2002-2006 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.springframework.aop.support;
018:
019: import org.apache.oro.text.regex.MalformedPatternException;
020: import org.apache.oro.text.regex.Pattern;
021: import org.apache.oro.text.regex.PatternMatcher;
022: import org.apache.oro.text.regex.Perl5Compiler;
023: import org.apache.oro.text.regex.Perl5Matcher;
024:
025: /**
026: * Perl5-style regular expression pointcut. JavaBean properties are:
027: * <ul>
028: * <li>pattern: Perl5 regular expression for the fully-qualified method names to match
029: * <li>patterns: alternative property taking a String array of patterns.
030: * The result will be the union of these patterns.
031: * </ul>
032: *
033: * <p>Note: the regular expressions must be a match. For example,
034: * <code>.*get.*</code> will match com.mycom.Foo.getBar().
035: * <code>get.*</code> will not.
036: *
037: * <p>Currently uses the <a href="http://jakarta.apache.org/oro">Jakarta ORO</a>
038: * regular expression library. Does not require JDK 1.4+, in contrast to
039: * JdkRegexpMethodPointcut.
040: *
041: * @author Rod Johnson
042: * @author Rob Harrop
043: * @since 1.1
044: * @see JdkRegexpMethodPointcut
045: */
046: public class Perl5RegexpMethodPointcut extends
047: AbstractRegexpMethodPointcut {
048:
049: /**
050: * ORO's compiled form of this pattern.
051: * ORO fields are transient as they're not serializable.
052: * They will be reinitialized on deserialization by
053: * the initPatternRepresentation() method.
054: */
055: private transient Pattern[] compiledPatterns = new Pattern[0];
056:
057: private transient Pattern[] compiledExclusionPatterns = new Pattern[0];
058:
059: /** ORO pattern matcher to use */
060: private transient PatternMatcher matcher;
061:
062: /**
063: * Initializes the {@link Pattern ORO representation} of the supplied exclusion patterns.
064: */
065: protected void initPatternRepresentation(String[] patterns)
066: throws IllegalArgumentException {
067: this .compiledPatterns = compilePatterns(patterns);
068: this .matcher = new Perl5Matcher();
069: }
070:
071: /**
072: * Returns <code>true</code> if the {@link Pattern} at index <code>patternIndex</code>
073: * matches the supplied candidate <code>String</code>.
074: */
075: protected boolean matches(String pattern, int patternIndex) {
076: return this .matcher.matches(pattern,
077: this .compiledPatterns[patternIndex]);
078: }
079:
080: /**
081: * Initializes the {@link Pattern ORO representation} of the supplied exclusion patterns.
082: */
083: protected void initExcludedPatternRepresentation(
084: String[] excludedPatterns) throws IllegalArgumentException {
085: this .compiledExclusionPatterns = compilePatterns(excludedPatterns);
086: }
087:
088: /**
089: * Returns <code>true</code> if the exclusion {@link Pattern} at index <code>patternIndex</code>
090: * matches the supplied candidate <code>String</code>.
091: */
092: protected boolean matchesExclusion(String pattern, int patternIndex) {
093: return this .matcher.matches(pattern,
094: this .compiledExclusionPatterns[patternIndex]);
095: }
096:
097: /**
098: * Compiles the supplied pattern sources into a {@link Pattern} array.
099: */
100: private Pattern[] compilePatterns(String[] source) {
101: Perl5Compiler compiler = new Perl5Compiler();
102: Pattern[] destination = new Pattern[source.length];
103: for (int i = 0; i < source.length; i++) {
104: // compile the pattern to be thread-safe
105: try {
106: destination[i] = compiler.compile(source[i],
107: Perl5Compiler.READ_ONLY_MASK);
108: } catch (MalformedPatternException ex) {
109: throw new IllegalArgumentException(ex.getMessage());
110: }
111: }
112: return destination;
113: }
114:
115: }
|