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.HashMap;
025:
026: import org.jboss.aop.joinpoint.Invocation;
027: import org.jboss.aspects.dbc.DesignByContractAspect;
028: import org.jboss.aspects.dbc.condition.parser.BeanshellGenerator;
029: import org.jboss.aspects.dbc.condition.parser.Expression;
030: import org.jboss.aspects.dbc.condition.parser.ExpressionParser;
031:
032: import bsh.Capabilities;
033:
034: /**
035: * Stores a
036: * @author <a href="mailto:kabir.khan@jboss.org">Kabir Khan</a>
037: * @version $Revision: 57186 $
038: */
039: public abstract class Condition {
040: public final static String TARGET = "tgt";
041: public final static String RETURN = "rtn";
042:
043: static {
044: //Make sure that the beanshell can access private fields and variables
045: Capabilities.setAccessibility(true);
046: }
047:
048: //Map of valid java identifiers to the original $tgt, $ret, $0, $1, $2 etc.
049: //used for the condition strings in the annotations
050: protected HashMap parameterLookup = new HashMap();
051: protected String originalExpr;
052: protected String condExpr;
053: protected Class clazz;
054:
055: //If this condition is for a static method or is a static invariant condition
056: protected boolean isStatic;
057:
058: public Condition(String condExpr, Class clazz, boolean isStatic) {
059: this .isStatic = isStatic;
060:
061: if (DesignByContractAspect.verbose)
062: System.out.println("[dbc] Initialising condition: "
063: + condExpr);
064: originalExpr = condExpr;
065: condExpr += " ";
066:
067: StringBuffer newcond = new StringBuffer();
068: StringBuffer param = null;
069:
070: for (int i = 0; i < condExpr.length(); i++) {
071: char c = condExpr.charAt(i);
072: if (c == '$') {
073: param = new StringBuffer();
074: continue;
075: } else if (param != null
076: && (c == '.' || c == ' ' || c == '=' || c == '>'
077: || c == '<' || c == ')' || c == '}'
078: || c == ';' || c == '[' || c == ']')) {
079: //Get param name as it was (without the leading '$')
080: String prm = param.toString();
081:
082: if (prm.equals(TARGET) && isStatic) {
083: //For a static method or static condition, use the class name instead of a parameter
084: newcond.append(clazz.getName());
085: } else {
086: //Get param name for beanshell
087: String bsparam = "p" + i;
088:
089: newcond.append(bsparam);
090: parameterLookup.put(bsparam, prm);
091: }
092:
093: param = null;
094: }
095:
096: if (param == null) {
097: newcond.append(c);
098: } else {
099: param.append(c);
100: }
101: }
102:
103: Expression expr = ExpressionParser.parseExpression(newcond
104: .toString());
105: BeanshellGenerator gen = new BeanshellGenerator(expr);
106: this .condExpr = gen.createBeanshellCode();
107:
108: if (DesignByContractAspect.verbose)
109: System.out.println("[dbc] Expanded to Java code:\n"
110: + this .condExpr);
111:
112: this .clazz = clazz;
113: }
114:
115: public String toString() {
116: return originalExpr;
117: }
118:
119: public boolean equals(Object o) {
120: if (o instanceof Condition) {
121: Condition c = (Condition) o;
122: return c.clazz.equals(clazz)
123: && originalExpr.equals(c.originalExpr);
124: }
125:
126: return false;
127: }
128:
129: public int hashCode() {
130: // TODO Auto-generated method stub
131: return originalExpr.hashCode();
132: }
133:
134: protected Object getTarget(Invocation invocation, boolean isStatic) {
135: if (!isStatic) {
136: return invocation.getTargetObject();
137: } else {
138: return clazz;
139: }
140: }
141: }
|