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.support;
018:
019: import java.io.Serializable;
020: import java.lang.reflect.Method;
021:
022: import org.springframework.aop.MethodMatcher;
023: import org.springframework.aop.Pointcut;
024: import org.springframework.util.Assert;
025:
026: /**
027: * Pointcut constants for matching getters and setters,
028: * and static methods useful for manipulating and evaluating pointcuts.
029: * These methods are particularly useful for composing pointcuts
030: * using the union and intersection methods.
031: *
032: * @author Rod Johnson
033: * @author Juergen Hoeller
034: */
035: public abstract class Pointcuts {
036:
037: /** Pointcut matching all bean property setters, in any class */
038: public static final Pointcut SETTERS = SetterPointcut.INSTANCE;
039:
040: /** Pointcut matching all bean property getters, in any class */
041: public static final Pointcut GETTERS = GetterPointcut.INSTANCE;
042:
043: /**
044: * Match all methods that <b>either</b> (or both) of the given pointcuts matches.
045: * @param pc1 the first Pointcut
046: * @param pc2 the second Pointcut
047: * @return a distinct Pointcut that matches all methods that either
048: * of the given Pointcuts matches
049: */
050: public static Pointcut union(Pointcut pc1, Pointcut pc2) {
051: return new ComposablePointcut(pc1).union(pc2);
052: }
053:
054: /**
055: * Match all methods that <b>both</b> the given pointcuts match.
056: * @param pc1 the first Pointcut
057: * @param pc2 the second Pointcut
058: * @return a distinct Pointcut that matches all methods that both
059: * of the given Pointcuts match
060: */
061: public static Pointcut intersection(Pointcut pc1, Pointcut pc2) {
062: return new ComposablePointcut(pc1).intersection(pc2);
063: }
064:
065: /**
066: * Perform the least expensive check for a pointcut match.
067: * @param pointcut the pointcut to match
068: * @param method the candidate method
069: * @param targetClass the target class
070: * @param args arguments to the method
071: * @return whether there's a runtime match
072: */
073: public static boolean matches(Pointcut pointcut, Method method,
074: Class targetClass, Object[] args) {
075: Assert.notNull(pointcut, "Pointcut must not be null");
076: if (pointcut == Pointcut.TRUE) {
077: return true;
078: }
079: if (pointcut.getClassFilter().matches(targetClass)) {
080: // Only check if it gets past first hurdle.
081: MethodMatcher mm = pointcut.getMethodMatcher();
082: if (mm.matches(method, targetClass)) {
083: // We may need additional runtime (argument) check.
084: return (!mm.isRuntime() || mm.matches(method,
085: targetClass, args));
086: }
087: }
088: return false;
089: }
090:
091: /**
092: * Pointcut implementation that matches bean property setters.
093: */
094: private static class SetterPointcut extends
095: StaticMethodMatcherPointcut implements Serializable {
096:
097: public static SetterPointcut INSTANCE = new SetterPointcut();
098:
099: public boolean matches(Method method, Class targetClass) {
100: return method.getName().startsWith("set")
101: && method.getParameterTypes().length == 1
102: && method.getReturnType() == Void.TYPE;
103: }
104:
105: private Object readResolve() {
106: return INSTANCE;
107: }
108: }
109:
110: /**
111: * Pointcut implementation that matches bean property getters.
112: */
113: private static class GetterPointcut extends
114: StaticMethodMatcherPointcut implements Serializable {
115:
116: public static GetterPointcut INSTANCE = new GetterPointcut();
117:
118: public boolean matches(Method method, Class targetClass) {
119: return method.getName().startsWith("get")
120: && method.getParameterTypes().length == 0;
121: }
122:
123: private Object readResolve() {
124: return INSTANCE;
125: }
126: }
127:
128: }
|