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 java.io.Serializable;
020: import java.lang.reflect.Method;
021: import java.util.LinkedList;
022: import java.util.List;
023:
024: import org.springframework.util.ObjectUtils;
025: import org.springframework.util.PatternMatchUtils;
026:
027: /**
028: * Pointcut bean for simple method name matches, as alternative to regexp patterns.
029: * Does not handle overloaded methods: all methods *with a given name will be eligible.
030: *
031: * @author Juergen Hoeller
032: * @author Rod Johnson
033: * @author Rob Harrop
034: * @since 11.02.2004
035: * @see #isMatch
036: */
037: public class NameMatchMethodPointcut extends
038: StaticMethodMatcherPointcut implements Serializable {
039:
040: private List mappedNames = new LinkedList();
041:
042: /**
043: * Convenience method when we have only a single method name to match.
044: * Use either this method or <code>setMappedNames</code>, not both.
045: * @see #setMappedNames
046: */
047: public void setMappedName(String mappedName) {
048: setMappedNames(new String[] { mappedName });
049: }
050:
051: /**
052: * Set the method names defining methods to match.
053: * Matching will be the union of all these; if any match,
054: * the pointcut matches.
055: */
056: public void setMappedNames(String[] mappedNames) {
057: this .mappedNames = new LinkedList();
058: if (mappedNames != null) {
059: for (int i = 0; i < mappedNames.length; i++) {
060: this .mappedNames.add(mappedNames[i]);
061: }
062: }
063: }
064:
065: /**
066: * Add another eligible method name, in addition to those already named.
067: * Like the set methods, this method is for use when configuring proxies,
068: * before a proxy is used.
069: * <p><b>NB:</b> This method does not work after the proxy is in
070: * use, as advice chains will be cached.
071: * @param name name of the additional method that will match
072: * @return this pointcut to allow for multiple additions in one line
073: */
074: public NameMatchMethodPointcut addMethodName(String name) {
075: // TODO in a future release, consider a way of letting proxies
076: // cause advice changed events.
077: this .mappedNames.add(name);
078: return this ;
079: }
080:
081: public boolean matches(Method method, Class targetClass) {
082: for (int i = 0; i < this .mappedNames.size(); i++) {
083: String mappedName = (String) this .mappedNames.get(i);
084: if (mappedName.equals(method.getName())
085: || isMatch(method.getName(), mappedName)) {
086: return true;
087: }
088: }
089: return false;
090: }
091:
092: /**
093: * Return if the given method name matches the mapped name.
094: * <p>The default implementation checks for "xxx*", "*xxx" and "*xxx*" matches,
095: * as well as direct equality. Can be overridden in subclasses.
096: * @param methodName the method name of the class
097: * @param mappedName the name in the descriptor
098: * @return if the names match
099: * @see org.springframework.util.PatternMatchUtils#simpleMatch(String, String)
100: */
101: protected boolean isMatch(String methodName, String mappedName) {
102: return PatternMatchUtils.simpleMatch(mappedName, methodName);
103: }
104:
105: public boolean equals(Object other) {
106: if (this == other) {
107: return true;
108: }
109: return (other instanceof NameMatchMethodPointcut && ObjectUtils
110: .nullSafeEquals(this .mappedNames,
111: ((NameMatchMethodPointcut) other).mappedNames));
112: }
113:
114: public int hashCode() {
115: return (this .mappedNames != null ? this .mappedNames.hashCode()
116: : 0);
117: }
118:
119: }
|