View Javadoc

1   /*
2    * Copyright 2004-2008 the Seasar Foundation and the Others.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13   * either express or implied. See the License for the specific language
14   * governing permissions and limitations under the License.
15   */
16  package org.seasar.cubby.aop;
17  
18  import java.io.Serializable;
19  import java.lang.reflect.Method;
20  import java.util.HashSet;
21  import java.util.Set;
22  import java.util.regex.Pattern;
23  
24  import org.seasar.cubby.util.CubbyUtils;
25  import org.seasar.framework.aop.Pointcut;
26  import org.seasar.framework.exception.EmptyRuntimeException;
27  
28  /**
29   * アクションメソッドに適用される {@link Pointcut}。
30   * 
31   * @author baba
32   */
33  public class ActionMethodPointcutImpl implements Pointcut, Serializable {
34  
35  	private static final long serialVersionUID = -5701826062675617117L;
36  
37  	private String[] methodNames;
38  
39  	private Pattern[] patterns;
40  
41  	/**
42  	 * {@link ActionMethodPointcutImpl}を作成します。
43  	 * 
44  	 * @param targetClass
45  	 * @throws EmptyRuntimeException
46  	 */
47  	public ActionMethodPointcutImpl(final Class<?> targetClass)
48  			throws EmptyRuntimeException {
49  
50  		if (targetClass == null) {
51  			throw new EmptyRuntimeException("targetClass");
52  		}
53  		setMethodNames(getMethodNames(targetClass));
54  	}
55  
56  	/**
57  	 * {@link ActionMethodPointcutImpl}を作成します。
58  	 * 
59  	 * @param methodNames
60  	 * @throws EmptyRuntimeException
61  	 */
62  	public ActionMethodPointcutImpl(final String[] methodNames)
63  			throws EmptyRuntimeException {
64  
65  		if (methodNames == null || methodNames.length == 0) {
66  			throw new EmptyRuntimeException("methodNames");
67  		}
68  		setMethodNames(methodNames);
69  	}
70  
71  	public boolean isApplied(final Method targetMethod) {
72  		if (!CubbyUtils.isActionMethod(targetMethod)) {
73  			return false;
74  		}
75  
76  		final String methodName = targetMethod.getName();
77  		for (int i = 0; i < patterns.length; ++i) {
78  			if (patterns[i].matcher(methodName).matches()) {
79  				return true;
80  			}
81  		}
82  		return false;
83  	}
84  
85  	/**
86  	 * 対象になったメソッド名の配列を返します。
87  	 * 
88  	 * @return 対象になったメソッド名の配列
89  	 */
90  	public String[] getMethodNames() {
91  		if (methodNames == null) {
92  			return null;
93  		}
94  		return methodNames.clone();
95  	}
96  
97  	private void setMethodNames(final String[] methodNames) {
98  		this.methodNames = methodNames;
99  		patterns = new Pattern[methodNames.length];
100 		for (int i = 0; i < patterns.length; ++i) {
101 			patterns[i] = Pattern.compile(methodNames[i]);
102 		}
103 	}
104 
105 	private static String[] getMethodNames(final Class<?> targetClass) {
106 		final Set<String> methodNameSet = new HashSet<String>();
107 		if (targetClass.isInterface()) {
108 			addInterfaceMethodNames(methodNameSet, targetClass);
109 		}
110 		for (Class<?> clazz = targetClass; clazz != Object.class
111 				&& clazz != null; clazz = clazz.getSuperclass()) {
112 			final Class<?>[] interfaces = clazz.getInterfaces();
113 			for (int i = 0; i < interfaces.length; ++i) {
114 				addInterfaceMethodNames(methodNameSet, interfaces[i]);
115 			}
116 		}
117 		return methodNameSet.toArray(new String[methodNameSet.size()]);
118 
119 	}
120 
121 	private static void addInterfaceMethodNames(
122 			final Set<String> methodNameSet, final Class<?> interfaceClass) {
123 		final Method[] methods = interfaceClass.getDeclaredMethods();
124 		for (int j = 0; j < methods.length; j++) {
125 			methodNameSet.add(methods[j].getName());
126 		}
127 		final Class<?>[] interfaces = interfaceClass.getInterfaces();
128 		for (int i = 0; i < interfaces.length; ++i) {
129 			addInterfaceMethodNames(methodNameSet, interfaces[i]);
130 		}
131 	}
132 
133 }