001: /*
002: * Copyright 2002-2007 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.beans.factory.support;
018:
019: import java.lang.reflect.Method;
020: import java.util.LinkedList;
021: import java.util.List;
022:
023: import org.springframework.util.Assert;
024: import org.springframework.util.ObjectUtils;
025:
026: /**
027: * Extension of MethodOverride that represents an arbitrary
028: * override of a method by the IoC container.
029: *
030: * <p>Any non-final method can be overridden, irrespective of its
031: * parameters and return types.
032: *
033: * @author Rod Johnson
034: * @author Juergen Hoeller
035: * @since 1.1
036: */
037: public class ReplaceOverride extends MethodOverride {
038:
039: private final String methodReplacerBeanName;
040:
041: /**
042: * List of String. Identifying signatures.
043: */
044: private List typeIdentifiers = new LinkedList();
045:
046: /**
047: * Construct a new ReplaceOverride.
048: * @param methodName the name of the method to override
049: * @param methodReplacerBeanName the bean name of the MethodReplacer
050: */
051: public ReplaceOverride(String methodName,
052: String methodReplacerBeanName) {
053: super (methodName);
054: Assert.notNull(methodName,
055: "Method replacer bean name must not be null");
056: this .methodReplacerBeanName = methodReplacerBeanName;
057: }
058:
059: /**
060: * Return the name of the bean implementing MethodReplacer.
061: */
062: public String getMethodReplacerBeanName() {
063: return this .methodReplacerBeanName;
064: }
065:
066: /**
067: * Add a fragment of a class string, like "Exception"
068: * or "java.lang.Exc", to identify a parameter type.
069: * @param identifier a substring of the fully qualified class name
070: */
071: public void addTypeIdentifier(String identifier) {
072: this .typeIdentifiers.add(identifier);
073: }
074:
075: public boolean matches(Method method) {
076: // TODO could cache result for efficiency
077: if (!method.getName().equals(getMethodName())) {
078: // It can't match.
079: return false;
080: }
081:
082: if (!isOverloaded()) {
083: // No overloaded: don't worry about arg type matching.
084: return true;
085: }
086:
087: // If we get to here, we need to insist on precise argument matching.
088: if (this .typeIdentifiers.size() != method.getParameterTypes().length) {
089: return false;
090: }
091: for (int i = 0; i < this .typeIdentifiers.size(); i++) {
092: String identifier = (String) this .typeIdentifiers.get(i);
093: if (method.getParameterTypes()[i].getName().indexOf(
094: identifier) == -1) {
095: // This parameter cannot match.
096: return false;
097: }
098: }
099: return true;
100: }
101:
102: public String toString() {
103: return "Replace override for method '" + getMethodName()
104: + "; will call bean '" + this .methodReplacerBeanName
105: + "'";
106: }
107:
108: public boolean equals(Object other) {
109: if (!(other instanceof ReplaceOverride) || !super .equals(other)) {
110: return false;
111: }
112: ReplaceOverride that = (ReplaceOverride) other;
113: return (ObjectUtils.nullSafeEquals(this .methodReplacerBeanName,
114: that.methodReplacerBeanName) && ObjectUtils
115: .nullSafeEquals(this .typeIdentifiers,
116: that.typeIdentifiers));
117: }
118:
119: public int hashCode() {
120: int hashCode = super .hashCode();
121: hashCode = 29
122: * hashCode
123: + ObjectUtils
124: .nullSafeHashCode(this .methodReplacerBeanName);
125: hashCode = 29 * hashCode
126: + ObjectUtils.nullSafeHashCode(this.typeIdentifiers);
127: return hashCode;
128: }
129:
130: }
|