// Copyright (C) 2003-2009 by Object Mentor, Inc. All rights reserved. // Released under the terms of the CPL Common Public License version 1.0. package fitnesse.slim; import static util.ListUtility.list; import java.util.ArrayList; import java.util.Collection; import java.util.List; /** * Specifies the syntactic operations for a Slim statement. A Slim statement is a list of strings. * The first string is the operation name. Other strings are arguments of the operation. This class knows * that syntax, and knows how to decompose it into StatementExecutor calls. This class DOES NOT know how * to do any actual execution. */ public class Statement { private ArrayList<Object> words = new ArrayList<Object>(); private NameTranslator methodNameTranslator; public Statement(List<Object> statement, NameTranslator methodNameTranslator) { this.methodNameTranslator = methodNameTranslator; for (Object word : statement) words.add(word); } public boolean add(Object s) { return words.add(s); } public boolean addAll(Collection<Object> objects) { return words.addAll(objects); } private boolean operationIs(String operation) { return getOperation().equalsIgnoreCase(operation); } public String getOperation() { return getWord(1); } private String getWord(int word) { try { return (String) words.get(word); } catch (Exception e) { throw new SlimError(String.format("message:<<MALFORMED_INSTRUCTION %s.>>", toString())); } } public String toString() { StringBuffer result = new StringBuffer(); result.append("["); for (Object word : words) { result.append(word); result.append(","); } int end = result.length() - 1; if (result.charAt(end) == ',') result.deleteCharAt(end); result.append("]"); return result.toString(); } public Object execute(StatementExecutorInterface executor) { Object retval; if (operationIs("make")) retval = createInstance(executor); else if (operationIs("import")) retval = addPath(executor); else if (operationIs("call")) retval = call(executor); else if (operationIs("callAndAssign")) retval = callAndAssign(executor); else retval = SlimServer.EXCEPTION_TAG + String.format("message:<<INVALID_STATEMENT: %s.>>", getOperation()); return list(getWord(0), retval); } private Object addPath(StatementExecutorInterface caller) { return caller.addPath(getWord(2)); } private Object createInstance(StatementExecutorInterface caller) { String instanceName = getWord(2); String className = getWord(3); Object[] args = makeArgsArray(4); return caller.create(instanceName, className, args); } private Object call(StatementExecutorInterface caller) { return callMethodAtIndex(caller, 2); } private Object callMethodAtIndex(StatementExecutorInterface caller, int methodIndex) { String instanceName = getWord(methodIndex + 0); String methodName = methodNameTranslator.translate(getWord(methodIndex + 1)); Object[] args = makeArgsArray(methodIndex + 2); return caller.call(instanceName, methodName, args); } private Object[] makeArgsArray(int argsIndex) { List<Object> argList = words.subList(argsIndex, words.size()); Object[] args = argList.toArray(new Object[argList.size()]); return args; } public Object callAndAssign(StatementExecutorInterface caller) { String instanceName = getWord(3); String methodName = methodNameTranslator.translate(getWord(4)); Object[] args = makeArgsArray(5); return caller.callAndAssign(getWord(2), instanceName, methodName, args); } }