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   * @since 1.0.0
33   */
34  public class ActionMethodPointcutImpl implements Pointcut, Serializable {
35  
36  	private static final long serialVersionUID = -5701826062675617117L;
37  
38  	private String[] methodNames;
39  
40  	private Pattern[] patterns;
41  
42  	/**
43  	 * {@link ActionMethodPointcutImpl}を作成します。
44  	 * 
45  	 * @param targetClass
46  	 * @throws EmptyRuntimeException
47  	 */
48  	public ActionMethodPointcutImpl(final Class<?> targetClass)
49  			throws EmptyRuntimeException {
50  
51  		if (targetClass == null) {
52  			throw new EmptyRuntimeException("targetClass");
53  		}
54  		setMethodNames(getMethodNames(targetClass));
55  	}
56  
57  	/**
58  	 * {@link ActionMethodPointcutImpl}を作成します。
59  	 * 
60  	 * @param methodNames
61  	 * @throws EmptyRuntimeException
62  	 */
63  	public ActionMethodPointcutImpl(final String[] methodNames)
64  			throws EmptyRuntimeException {
65  
66  		if (methodNames == null || methodNames.length == 0) {
67  			throw new EmptyRuntimeException("methodNames");
68  		}
69  		setMethodNames(methodNames);
70  	}
71  
72  	/**
73  	 * {@inheritDoc}
74  	 */
75  	public boolean isApplied(final Method targetMethod) {
76  		if (!CubbyUtils.isActionMethod(targetMethod)) {
77  			return false;
78  		}
79  
80  		final String methodName = targetMethod.getName();
81  		for (int i = 0; i < patterns.length; ++i) {
82  			if (patterns[i].matcher(methodName).matches()) {
83  				return true;
84  			}
85  		}
86  		return false;
87  	}
88  
89  	/**
90  	 * 対象になったメソッド名の配列を返します。
91  	 * 
92  	 * @return 対象になったメソッド名の配列
93  	 */
94  	public String[] getMethodNames() {
95  		if (methodNames == null) {
96  			return null;
97  		}
98  		return methodNames.clone();
99  	}
100 
101 	private void setMethodNames(final String[] methodNames) {
102 		this.methodNames = methodNames;
103 		patterns = new Pattern[methodNames.length];
104 		for (int i = 0; i < patterns.length; ++i) {
105 			patterns[i] = Pattern.compile(methodNames[i]);
106 		}
107 	}
108 
109 	private static String[] getMethodNames(final Class<?> targetClass) {
110 		final Set<String> methodNameSet = new HashSet<String>();
111 		if (targetClass.isInterface()) {
112 			addInterfaceMethodNames(methodNameSet, targetClass);
113 		}
114 		for (Class<?> clazz = targetClass; clazz != Object.class
115 				&& clazz != null; clazz = clazz.getSuperclass()) {
116 			final Class<?>[] interfaces = clazz.getInterfaces();
117 			for (int i = 0; i < interfaces.length; ++i) {
118 				addInterfaceMethodNames(methodNameSet, interfaces[i]);
119 			}
120 		}
121 		return methodNameSet.toArray(new String[methodNameSet.size()]);
122 
123 	}
124 
125 	private static void addInterfaceMethodNames(
126 			final Set<String> methodNameSet, final Class<?> interfaceClass) {
127 		final Method[] methods = interfaceClass.getDeclaredMethods();
128 		for (int j = 0; j < methods.length; j++) {
129 			methodNameSet.add(methods[j].getName());
130 		}
131 		final Class<?>[] interfaces = interfaceClass.getInterfaces();
132 		for (int i = 0; i < interfaces.length; ++i) {
133 			addInterfaceMethodNames(methodNameSet, interfaces[i]);
134 		}
135 	}
136 
137 }