001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.aspects.dbc.condition;
023:
024: import java.lang.reflect.Method;
025: import java.util.ArrayList;
026:
027: import javassist.Modifier;
028:
029: import org.jboss.aop.annotation.AnnotationElement;
030: import org.jboss.aspects.dbc.DesignByContractAspect;
031: import org.jboss.aspects.dbc.PostCond;
032: import org.jboss.aspects.dbc.PreCond;
033:
034: /**
035: *
036: * @author <a href="mailto:kabir.khan@jboss.org">Kabir Khan</a>
037: * @version $Revision: 57186 $
038: */
039: public class MethodConditionManager extends ConditionManager {
040: public static synchronized ExecutableCondition[] getPreConditions(
041: Method method) {
042: ExecutableCondition[] pre = (ExecutableCondition[]) preConditions
043: .get(method);
044: if (pre != null) {
045: return pre;
046: }
047:
048: initialise(method);
049: return (ExecutableCondition[]) preConditions.get(method);
050: }
051:
052: public static synchronized ExecutableCondition[] getPostConditions(
053: Method method) {
054: ExecutableCondition[] post = (ExecutableCondition[]) postConditions
055: .get(method);
056: if (post != null) {
057: return post;
058: }
059:
060: initialise(method);
061: return (ExecutableCondition[]) postConditions.get(method);
062: }
063:
064: public static synchronized InvariantCondition[] getInvariants(
065: Method method) {
066: return getInvariants(method.getDeclaringClass());
067: }
068:
069: private static void initialise(Method method) {
070: if (DesignByContractAspect.verbose)
071: System.out.println("[dbc] ===== Intitalising method: "
072: + method);
073: ArrayList preConds = new ArrayList();
074: ArrayList postConds = new ArrayList();
075:
076: //Need @PreCond and @PostCond for this method, and all the super
077: //declarations of the method.
078: //Likewise we need the @Invariant for this class and the super classes
079: boolean first = true;
080:
081: Class clazz = method.getDeclaringClass();
082: Class curClazz = clazz;
083: Method super Method = method;
084:
085: while (curClazz != null) {
086: if (first) {
087: first = false;
088: } else {
089: super Method = findMethodInClass(curClazz, method);
090: }
091:
092: if (super Method != null) {
093: addMethodConditions(method, super Method, preConds,
094: postConds);
095: }
096:
097: addMethodConditionsForInterfaces(preConds, postConds,
098: curClazz, method);
099:
100: curClazz = curClazz.getSuperclass();
101: }
102:
103: ExecutableCondition[] pre = (ExecutableCondition[]) preConds
104: .toArray(new ExecutableCondition[preConds.size()]);
105: preConditions.put(method, pre);
106:
107: ExecutableCondition[] post = (ExecutableCondition[]) postConds
108: .toArray(new ExecutableCondition[postConds.size()]);
109: postConditions.put(method, post);
110: }
111:
112: private static void addMethodConditionsForInterfaces(
113: ArrayList preConds, ArrayList postConds, Class clazz,
114: Method method) {
115: Class[] interfaces = clazz.getInterfaces();
116: for (int i = 0; i < interfaces.length; i++) {
117: //System.out.println("Checking interface: " + interfaces[i]);
118: Method foundMethod = findMethodInClass(interfaces[i],
119: method);
120:
121: if (foundMethod != null) {
122: //System.out.println("Found method: " + foundMethod);
123: addMethodConditions(method, foundMethod, preConds,
124: postConds);
125: }
126: }
127:
128: }
129:
130: private static void addMethodConditions(Method realMethod,
131: Method currentMethod, ArrayList preConds,
132: ArrayList postConds) {
133: PreCond pre = (PreCond) AnnotationElement.getAnyAnnotation(
134: currentMethod, PreCond.class);
135: if (pre != null) {
136: if (DesignByContractAspect.verbose)
137: System.out
138: .println("[dbc] Found preconditions in method: "
139: + currentMethod);
140: addMethodConditions(realMethod, preConds, pre.value());
141: }
142:
143: PostCond post = (PostCond) AnnotationElement.getAnyAnnotation(
144: currentMethod, PostCond.class);
145: if (post != null) {
146: if (DesignByContractAspect.verbose)
147: System.out
148: .println("[dbc] Found postconditions in method: "
149: + currentMethod);
150: addMethodConditions(realMethod, postConds, post.value());
151: }
152: }
153:
154: private static ArrayList addMethodConditions(Method realMethod,
155: ArrayList conditions, String[] exprs) {
156: if (exprs == null) {
157: return conditions;
158: }
159:
160: boolean staticCall = Modifier.isStatic(realMethod
161: .getModifiers());
162:
163: for (int i = 0; i < exprs.length; i++) {
164: conditions.add(new MethodCondition(realMethod, exprs[i],
165: staticCall));
166: }
167:
168: return conditions;
169: }
170:
171: private static Method findMethodInClass(Class clazz, Method method) {
172: String name = method.getName();
173: Method[] methods = clazz.getDeclaredMethods();
174: for (int i = 0; i < methods.length; i++) {
175: if (methods[i].getName().equals(name)) {
176: Class[] soughtParams = method.getParameterTypes();
177: Class[] foundParams = methods[i].getParameterTypes();
178:
179: if (soughtParams.length == foundParams.length) {
180: for (int j = 0; j < soughtParams.length; j++) {
181: if (soughtParams[j] != foundParams[j]) {
182: break;
183: }
184: }
185:
186: return methods[i];
187: }
188: }
189: }
190: return null;
191: }
192:
193: }
|