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.util.Iterator;
025:
026: import org.jboss.aop.joinpoint.Invocation;
027: import org.jboss.aspects.dbc.DesignByContractAspect;
028:
029: import bsh.EvalError;
030: import bsh.Interpreter;
031:
032: /**
033: * A pre or post consition
034: * @author <a href="mailto:kabir.khan@jboss.org">Kabir Khan</a>
035: * @version $Revision: 57186 $
036: */
037: public abstract class ExecutableCondition extends Condition {
038: public ExecutableCondition(String condExpr, Class clazz,
039: boolean isStatic) {
040: super (condExpr, clazz, isStatic);
041: }
042:
043: public void evaluateCondition(DesignByContractAspect aspect,
044: Invocation inv, Object[] args, Object ret) {
045: try {
046: if (DesignByContractAspect.verbose)
047: System.out
048: .println("[dbc] Evaluate condition : '"
049: + originalExpr + "' for: "
050: + executableObject());
051:
052: Interpreter interpreter = new Interpreter();
053: for (Iterator it = parameterLookup.keySet().iterator(); it
054: .hasNext();) {
055: String beanshellname = (String) it.next();
056: String originalname = (String) parameterLookup
057: .get(beanshellname);
058: Object value = getValueForToken(inv, args, ret,
059: originalname);
060: interpreter.set(beanshellname, value);
061: if (DesignByContractAspect.verbose)
062: System.out.println("[dbc] Setting $"
063: + originalname
064: + " to "
065: + value
066: + ((value != null) ? " (type: "
067: + value.getClass().getName() + ")"
068: : ""));
069: }
070:
071: Boolean eval = (Boolean) interpreter.eval(condExpr);
072:
073: if (!eval.booleanValue()) {
074: System.out.println("CONDITION BROKEN: " + originalExpr
075: + " - " + executableObject());
076: throw new RuntimeException("Condition " + originalExpr
077: + " was broken " + "for: " + executableObject());
078: }
079: } catch (EvalError e) {
080: throw new RuntimeException(
081: "There was an error in the expression: "
082: + originalExpr, e);
083: }
084: }
085:
086: public String toString() {
087: return executableObject() + ":" + super .toString();
088: }
089:
090: protected Object getValueForToken(Invocation invocation,
091: Object[] args, Object rtn, String token) {
092: if (isPredefinedToken(token)) {
093: return getValueForPredefinedToken(invocation, rtn, token);
094: }
095:
096: try {
097: int i = Integer.parseInt(token);
098: return args[i];
099: } catch (NumberFormatException e) {
100: throw new RuntimeException("Invalid token '$" + token
101: + "' in condition: " + originalExpr);
102: } catch (ArrayIndexOutOfBoundsException e) {
103: throw new RuntimeException("invalid parameter number '$"
104: + token + "' in condition: " + originalExpr + ". "
105: + executableObject() + " takes "
106: + parameterTypes().length);
107: }
108: }
109:
110: protected abstract boolean isPredefinedToken(String token);
111:
112: protected abstract Object getValueForPredefinedToken(
113: Invocation invocation, Object rtn, String token);
114:
115: protected abstract Object executableObject();
116:
117: protected abstract Class[] parameterTypes();
118:
119: }
|