View Javadoc

1   package org.seasar.cubby.aop;
2   
3   import java.io.Serializable;
4   import java.lang.reflect.Method;
5   import java.util.HashSet;
6   import java.util.Set;
7   import java.util.regex.Pattern;
8   
9   import org.seasar.cubby.util.CubbyUtils;
10  import org.seasar.framework.aop.Pointcut;
11  import org.seasar.framework.exception.EmptyRuntimeException;
12  
13  /**
14   * アクションメソッドに適用される {@link Pointcut}。
15   * 
16   * @author baba
17   */
18  public class ActionMethodPointcutImpl implements Pointcut, Serializable {
19  
20  	private static final long serialVersionUID = -5701826062675617117L;
21  
22  	private String[] methodNames;
23  
24  	private Pattern[] patterns;
25  
26  	/**
27  	 * {@link ActionMethodPointcutImpl}を作成します。
28  	 * 
29  	 * @param targetClass
30  	 * @throws EmptyRuntimeException
31  	 */
32  	public ActionMethodPointcutImpl(final Class<?> targetClass)
33  			throws EmptyRuntimeException {
34  
35  		if (targetClass == null) {
36  			throw new EmptyRuntimeException("targetClass");
37  		}
38  		setMethodNames(getMethodNames(targetClass));
39  	}
40  
41  	/**
42  	 * {@link ActionMethodPointcutImpl}を作成します。
43  	 * 
44  	 * @param methodNames
45  	 * @throws EmptyRuntimeException
46  	 */
47  	public ActionMethodPointcutImpl(final String[] methodNames)
48  			throws EmptyRuntimeException {
49  
50  		if (methodNames == null || methodNames.length == 0) {
51  			throw new EmptyRuntimeException("methodNames");
52  		}
53  		setMethodNames(methodNames);
54  	}
55  
56  	public boolean isApplied(final Method targetMethod) {
57  		if (!CubbyUtils.isActionMethod(targetMethod)) {
58  			return false;
59  		}
60  
61  		final String methodName = targetMethod.getName();
62  		for (int i = 0; i < patterns.length; ++i) {
63  			if (patterns[i].matcher(methodName).matches()) {
64  				return true;
65  			}
66  		}
67  		return false;
68  	}
69  
70  	/**
71  	 * 対象になったメソッド名の配列を返します。
72  	 * 
73  	 * @return 対象になったメソッド名の配列
74  	 */
75  	public String[] getMethodNames() {
76  		if (methodNames == null) {
77  			return null;
78  		}
79  		return methodNames.clone();
80  	}
81  
82  	private void setMethodNames(final String[] methodNames) {
83  		this.methodNames = methodNames;
84  		patterns = new Pattern[methodNames.length];
85  		for (int i = 0; i < patterns.length; ++i) {
86  			patterns[i] = Pattern.compile(methodNames[i]);
87  		}
88  	}
89  
90  	private static String[] getMethodNames(final Class<?> targetClass) {
91  		final Set<String> methodNameSet = new HashSet<String>();
92  		if (targetClass.isInterface()) {
93  			addInterfaceMethodNames(methodNameSet, targetClass);
94  		}
95  		for (Class<?> clazz = targetClass; clazz != Object.class
96  				&& clazz != null; clazz = clazz.getSuperclass()) {
97  			final Class<?>[] interfaces = clazz.getInterfaces();
98  			for (int i = 0; i < interfaces.length; ++i) {
99  				addInterfaceMethodNames(methodNameSet, interfaces[i]);
100 			}
101 		}
102 		return methodNameSet.toArray(new String[methodNameSet.size()]);
103 
104 	}
105 
106 	private static void addInterfaceMethodNames(
107 			final Set<String> methodNameSet, final Class<?> interfaceClass) {
108 		final Method[] methods = interfaceClass.getDeclaredMethods();
109 		for (int j = 0; j < methods.length; j++) {
110 			methodNameSet.add(methods[j].getName());
111 		}
112 		final Class<?>[] interfaces = interfaceClass.getInterfaces();
113 		for (int i = 0; i < interfaces.length; ++i) {
114 			addInterfaceMethodNames(methodNameSet, interfaces[i]);
115 		}
116 	}
117 
118 }