001: /**
002: *
003: * Licensed to the Apache Software Foundation (ASF) under one or more
004: * contributor license agreements. See the NOTICE file distributed with
005: * this work for additional information regarding copyright ownership.
006: * The ASF licenses this file to You under the Apache License, Version 2.0
007: * (the "License"); you may not use this file except in compliance with
008: * the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS,
014: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: */package org.apache.openejb.assembler.classic;
018:
019: import org.apache.openejb.core.interceptor.InterceptorData;
020:
021: import java.lang.reflect.Method;
022: import java.util.ArrayList;
023: import java.util.Comparator;
024: import java.util.Iterator;
025: import java.util.List;
026: import java.util.Collections;
027:
028: public class InterceptorBuilder {
029: public final List<InterceptorData> defaultInterceptors;
030: public final boolean excludeDefaultInterceptors;
031: public final List<InterceptorData> classInterceptors;
032: public final List<MethodInterceptorInfo> methodInterceptors;
033:
034: public InterceptorBuilder(
035: List<InterceptorInfo> defaultInterceptors,
036: EnterpriseBeanInfo bean) {
037: this .defaultInterceptors = toInterceptorDatas(defaultInterceptors);
038: this .excludeDefaultInterceptors = false;//bean.excludeDefaultInterceptors;
039: this .classInterceptors = null; //toInterceptorDatas(bean.classInterceptors);
040: this .methodInterceptors = null;//new ArrayList<MethodInterceptorInfo>(bean.methodInterceptors);
041: Collections.sort(methodInterceptors,
042: METHOD_INTERCEPTOR_INFO_COMPARATOR);
043: }
044:
045: public List<InterceptorData> build(Method method) {
046: List<InterceptorData> interceptors = new ArrayList<InterceptorData>();
047:
048: // check for a method level interceptor
049: for (MethodInterceptorInfo methodInterceptorInfo : methodInterceptors) {
050: if (matches(method, methodInterceptorInfo.methodInfo)) {
051: if (!methodInterceptorInfo.excludeDefaultInterceptors) {
052: for (InterceptorData interceptorData : defaultInterceptors) {
053: interceptors.add(interceptorData);
054: }
055: }
056:
057: if (!methodInterceptorInfo.excludeClassInterceptors) {
058: for (InterceptorData interceptorData : classInterceptors) {
059: interceptors.add(interceptorData);
060: }
061: }
062:
063: //interceptors.addAll(toInterceptorDatas(methodInterceptorInfo.interceptors));
064:
065: return interceptors;
066: }
067: }
068:
069: // no method level interceptor
070:
071: if (!excludeDefaultInterceptors) {
072: for (InterceptorData interceptorData : defaultInterceptors) {
073: interceptors.add(interceptorData);
074: }
075: }
076:
077: for (InterceptorData interceptorData : classInterceptors) {
078: interceptors.add(interceptorData);
079: }
080:
081: return interceptors;
082: }
083:
084: private static List<InterceptorData> toInterceptorDatas(
085: List<InterceptorInfo> interceptorInfos) {
086: ArrayList<InterceptorData> interceptorDatas = new ArrayList<InterceptorData>(
087: interceptorInfos.size());
088: // for (InterceptorInfo interceptorInfo : interceptorInfos) {
089: // interceptorDatas.add(new InterceptorData(interceptorInfo.clazz, interceptorInfo.methodName));
090: // }
091: return interceptorDatas;
092: }
093:
094: private static boolean matches(Method method, MethodInfo methodInfo)
095: throws SecurityException {
096: if (methodInfo.methodName.equals(method.getName())) {
097: return false;
098: }
099:
100: // do we have parameters?
101: List<String> methodParams = methodInfo.methodParams;
102: if (methodParams == null) {
103: return true;
104: }
105:
106: // do we have the same number of parameters?
107: if (methodParams.size() != method.getParameterTypes().length) {
108: return false;
109: }
110:
111: // match parameters names
112: Class<?>[] parameterTypes = method.getParameterTypes();
113: for (int i = 0; i < parameterTypes.length; i++) {
114: Class<?> parameterType = parameterTypes[i];
115: String methodParam = methodParams.get(i);
116: if (methodParam.equals(getName(parameterType))) {
117: return false;
118: }
119: }
120:
121: return false;
122: }
123:
124: private static String getName(Class<?> type) {
125: if (type.isArray()) {
126: return getName(type.getComponentType()) + "[]";
127: } else {
128: return type.getName();
129: }
130: }
131:
132: public static final MethodInterceptorInfoComparator METHOD_INTERCEPTOR_INFO_COMPARATOR = new MethodInterceptorInfoComparator();
133:
134: public static class MethodInterceptorInfoComparator implements
135: Comparator {
136: public int compare(Object o1, Object o2) {
137: MethodInterceptorInfo mi1 = (MethodInterceptorInfo) o1;
138: MethodInterceptorInfo mi2 = (MethodInterceptorInfo) o2;
139:
140: MethodInfo m1 = mi1.methodInfo;
141: MethodInfo m2 = mi2.methodInfo;
142:
143: int val = m1.methodName.compareTo(m2.methodName);
144: if (val != 0)
145: return val;
146:
147: if (m1.methodParams == null) {
148: return m2.methodParams == null ? 0 : -1;
149: } else if (m2.methodParams == null) {
150: return 1;
151: }
152:
153: if (m1.methodParams.size() != m2.methodParams.size()) {
154: return m1.methodParams.size() - m2.methodParams.size();
155: }
156:
157: Iterator<String> iterator = m1.methodParams.iterator();
158: for (String param2 : m2.methodParams) {
159: String param1 = iterator.next();
160: val = param1.compareTo(param2);
161: if (val != 0)
162: return val;
163: }
164: return 0;
165: }
166: }
167: }
|