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.aop.framework;
018:
019: import java.util.Arrays;
020:
021: import org.springframework.aop.SpringProxy;
022: import org.springframework.aop.support.AopUtils;
023: import org.springframework.util.Assert;
024:
025: /**
026: * Utility methods for AOP proxy factories.
027: * Mainly for internal use within the AOP framework.
028: *
029: * <p>See {@link org.springframework.aop.support.AopUtils} for a collection of
030: * generic AOP utility methods which do not depend on AOP framework internals.
031: *
032: * @author Rod Johnson
033: * @author Juergen Hoeller
034: * @see org.springframework.aop.support.AopUtils
035: */
036: public abstract class AopProxyUtils {
037:
038: /**
039: * Determine the target class of the given bean instance,
040: * which might be an AOP proxy.
041: * <p>Returns the target class for an AOP proxy and the plain class else.
042: * @param candidate the instance to check (might be an AOP proxy)
043: * @return the target class (or the plain class of the given object as fallback)
044: * @deprecated as of Spring 2.0.3, in favor of <code>AopUtils.getTargetClass</code>
045: * @see org.springframework.aop.support.AopUtils#getTargetClass(Object)
046: */
047: public static Class getTargetClass(Object candidate) {
048: Assert.notNull(candidate, "Candidate object must not be null");
049: if (AopUtils.isCglibProxy(candidate)) {
050: return candidate.getClass().getSuperclass();
051: }
052: if (candidate instanceof Advised) {
053: return ((Advised) candidate).getTargetSource()
054: .getTargetClass();
055: }
056: return candidate.getClass();
057: }
058:
059: /**
060: * Determine the complete set of interfaces to proxy for the given AOP configuration.
061: * <p>This will always add the {@link Advised} interface unless the AdvisedSupport's
062: * {@link AdvisedSupport#setOpaque "opaque"} flag is on. Always adds the
063: * {@link org.springframework.aop.SpringProxy} marker interface.
064: * @return the complete set of interfaces to proxy
065: * @see Advised
066: * @see org.springframework.aop.SpringProxy
067: */
068: public static Class[] completeProxiedInterfaces(
069: AdvisedSupport advised) {
070: Class[] specifiedInterfaces = advised.getProxiedInterfaces();
071: if (specifiedInterfaces.length == 0) {
072: // No user-specified interfaces: check whether target class is an interface.
073: Class targetClass = advised.getTargetClass();
074: if (targetClass != null && targetClass.isInterface()) {
075: specifiedInterfaces = new Class[] { targetClass };
076: }
077: }
078: boolean addSpringProxy = !advised
079: .isInterfaceProxied(SpringProxy.class);
080: boolean addAdvised = !advised.isOpaque()
081: && !advised.isInterfaceProxied(Advised.class);
082: int nonUserIfcCount = 0;
083: if (addSpringProxy) {
084: nonUserIfcCount++;
085: }
086: if (addAdvised) {
087: nonUserIfcCount++;
088: }
089: Class[] proxiedInterfaces = new Class[specifiedInterfaces.length
090: + nonUserIfcCount];
091: System.arraycopy(specifiedInterfaces, 0, proxiedInterfaces, 0,
092: specifiedInterfaces.length);
093: if (addSpringProxy) {
094: proxiedInterfaces[specifiedInterfaces.length] = SpringProxy.class;
095: }
096: if (addAdvised) {
097: proxiedInterfaces[proxiedInterfaces.length - 1] = Advised.class;
098: }
099: return proxiedInterfaces;
100: }
101:
102: /**
103: * Extract the user-specified interfaces that the given proxy implements,
104: * i.e. all non-Advised interfaces that the proxy implements.
105: * @param proxy the proxy to analyze (usually a JDK dynamic proxy)
106: * @return all user-specified interfaces that the proxy implements,
107: * in the original order (never <code>null</code> or empty)
108: * @see Advised
109: */
110: public static Class[] proxiedUserInterfaces(Object proxy) {
111: Class[] proxyInterfaces = proxy.getClass().getInterfaces();
112: int nonUserIfcCount = 0;
113: if (proxy instanceof SpringProxy) {
114: nonUserIfcCount++;
115: }
116: if (proxy instanceof Advised) {
117: nonUserIfcCount++;
118: }
119: Class[] userInterfaces = new Class[proxyInterfaces.length
120: - nonUserIfcCount];
121: System.arraycopy(proxyInterfaces, 0, userInterfaces, 0,
122: userInterfaces.length);
123: Assert.notEmpty(userInterfaces,
124: "JDK proxy must implement one or more interfaces");
125: return userInterfaces;
126: }
127:
128: /**
129: * Check equality of the proxies behind the given AdvisedSupport objects.
130: * Not the same as equality of the AdvisedSupport objects:
131: * rather, equality of interfaces, advisors and target sources.
132: */
133: public static boolean equalsInProxy(AdvisedSupport a,
134: AdvisedSupport b) {
135: return (a == b || (equalsProxiedInterfaces(a, b)
136: && equalsAdvisors(a, b) && a.getTargetSource().equals(
137: b.getTargetSource())));
138: }
139:
140: /**
141: * Check equality of the proxied interfaces behind the given AdvisedSupport objects.
142: */
143: public static boolean equalsProxiedInterfaces(AdvisedSupport a,
144: AdvisedSupport b) {
145: return Arrays.equals(a.getProxiedInterfaces(), b
146: .getProxiedInterfaces());
147: }
148:
149: /**
150: * Check equality of the advisors behind the given AdvisedSupport objects.
151: */
152: public static boolean equalsAdvisors(AdvisedSupport a,
153: AdvisedSupport b) {
154: return Arrays.equals(a.getAdvisors(), b.getAdvisors());
155: }
156:
157: }
|