package org.marketcetera.strategy; import java.util.HashMap; import java.util.Map; import org.apache.bsf.BSFException; import org.jruby.exceptions.RaiseException; import org.marketcetera.core.ClassVersion; /* $License$ */ /** * {@link Executor} implementation for Ruby strategies. * * @author <a href="mailto:colin@marketcetera.com">Colin DuPlantis</a> * @version $Id: RubyExecutor.java 16154 2012-07-14 16:34:05Z colin $ * @since 1.0.0 */ @ClassVersion("$Id: RubyExecutor.java 16154 2012-07-14 16:34:05Z colin $") class RubyExecutor extends AbstractExecutor { /** * Create a new RubyExecutor instance. * * @param inStrategy a <code>Strategy</code> value */ RubyExecutor(Strategy inStrategy) { super(inStrategy); } /* (non-Javadoc) * @see org.marketcetera.strategy.Executor#interpretRuntimeException(java.lang.Exception) */ @Override public String interpretRuntimeException(Exception inE) { return exceptionAsString(inE); } /* (non-Javadoc) * @see org.marketcetera.strategy.AbstractExecutor#preprocess(java.lang.String) */ @Override protected String preprocess(String inScript) throws StrategyException { // in order to return a RunningStrategy object, it is necessary to tack on a "new" call to the end of the script // this is why we need to know the name of the class that the user intends to be the main class of the strategy StringBuilder fullScript = new StringBuilder(); fullScript.append(inScript); fullScript.append("\n").append(getStrategy().getName()).append(".new\n"); //$NON-NLS-1$ //$NON-NLS-2$ String processedScript = fullScript.toString(); return processedScript; } /* (non-Javadoc) * @see org.marketcetera.strategy.AbstractExecutor#getExecutionEngine() */ @Override protected ExecutionEngine getExecutionEngine() throws StrategyException { return new BeanScriptingFrameworkEngine(); } /** * Attempts to interpret the given exception in a Ruby context. * * @param inE an <code>Exception</code> * @return a <code>String</code> describing the exception's contents */ static String exceptionAsString(Exception inE) { RaiseException raiseException = null; if(inE instanceof RaiseException) { raiseException = (RaiseException)inE; } else if(inE instanceof BSFException && ((BSFException)inE).getTargetException() instanceof RaiseException) { raiseException = (RaiseException)((BSFException)inE).getTargetException(); } if(raiseException != null) { return String.format("%s %s", //$NON-NLS-1$ raiseException.getException().toString(), raiseException.getException().backtrace().toString()); } return inE.toString(); } /* (non-Javadoc) * @see org.marketcetera.strategy.Executor#translateMethodName(java.lang.String) */ @Override public String translateMethodName(String inMethodName) { return methodNames.get(inMethodName); } /** * method name translation */ private static final Map<String,String> methodNames = new HashMap<String,String>(); /** * static initialized for class */ static { methodNames.put("onAsk", //$NON-NLS-1$ "on_ask"); //$NON-NLS-1$ methodNames.put("onBid", //$NON-NLS-1$ "on_bid"); //$NON-NLS-1$ methodNames.put("onMarketstat", //$NON-NLS-1$ "on_marketstat"); //$NON-NLS-1$ methodNames.put("onDividend", //$NON-NLS-1$ "on_dividend"); //$NON-NLS-1$ methodNames.put("onCancelReject", //$NON-NLS-1$ "on_cancel_reject"); //$NON-NLS-1$ methodNames.put("onExecutionReport", //$NON-NLS-1$ "on_execution_report"); //$NON-NLS-1$ methodNames.put("onTrade", //$NON-NLS-1$ "on_trade"); //$NON-NLS-1$ methodNames.put("onOther", //$NON-NLS-1$ "on_other"); //$NON-NLS-1$ methodNames.put("onCallback", //$NON-NLS-1$ "on_callback"); //$NON-NLS-1$ methodNames.put("onStart", //$NON-NLS-1$ "on_start"); //$NON-NLS-1$ methodNames.put("onStop", //$NON-NLS-1$ "on_stop"); //$NON-NLS-1$ } }