package org.musetest.core.step;

import org.musetest.core.*;
import org.musetest.core.context.*;
import org.musetest.core.resource.*;
import org.musetest.core.steptest.*;
import org.musetest.core.values.*;

/**
 * Abstract base step implementation with some convenience methods for using value sources.
 * Also implements execute() to raise start and end events. Subclasses should override executeStep()
 * instead of execute() unless they take responsibility for raising those events.
 *
 * @author Christopher L Merrill (see LICENSE.txt for license details)
 */
public abstract class BaseStep implements MuseStep
    {
    public BaseStep(StepConfiguration configuration)
        {
        _config = configuration;
        }

    @Override
    public StepConfiguration getConfiguration()
        {
        return _config;
        }

    /**
     * Allows for future functionality to be performed before/after the actual implementation of the step.
     */
    @Override
    public StepExecutionResult execute(StepExecutionContext context) throws MuseExecutionError
        {
        return executeImplementation(context);
        }

    /**
     * Called by BaseStep.execute(). Subclasses should override this instead of execute()... or else take
     * responsibility for raising the start/end step events
     *
     * @param context The context in which the step is executed
     * @throws StepExecutionError If the step cannot be executed.
     */
    protected abstract StepExecutionResult executeImplementation(StepExecutionContext context) throws MuseExecutionError;

    /**
     * A convenience method to get a specific value source from the configuration parameter list.
     * @see BaseValueSource#getValueSource
     */
    protected MuseValueSource getValueSource(StepConfiguration config, String name, boolean required, MuseProject project) throws MuseInstantiationException
        {
        return BaseValueSource.getValueSource(config, name, required, project);
        }

    /**
     * A convenience method to resolves a value source to the desired type.
     * @see BaseValueSource#getValueSource
     */
    protected <T> T getValue(MuseValueSource source, StepExecutionContext context, boolean null_allowed, Class<T> type) throws ValueSourceResolutionError
        {
        return BaseValueSource.getValue(source, context, null_allowed, type);
        }

    /**
     * A convenience method to resolve a value source to the desired type with a default value.
     * @see BaseValueSource#getValueSource
     */
    protected <T> T getValue(MuseValueSource source, StepExecutionContext context, Class<T> type, T default_value) throws ValueSourceResolutionError
        {
        T result = BaseValueSource.getValue(source, context, true, type);
        if (result == null)
            return default_value;
        return result;
        }

    private StepConfiguration _config;
    }



@@ -2853,24 +2853,1198 @@
 %0A        %7D%0A%0A
+    protected %3CT%3E T getVariable(StepExecutionContext context, String varname, Class%3CT%3E type) throws MuseExecutionError%0A        %7B%0A        Object value = context.getVariable(varname);%0A        if (value == null)%0A            throw new MuseExecutionError(String.format(%22Unable to get variable '%25s' from the context. A %25s is required.%22, varname, type.getSimpleName()));%0A        if (type.isAssignableFrom(value.getClass()))%0A            return (T) value;%0A        throw new MuseExecutionError(String.format(%22Variable '%25s' in the context is a %25s, but a %25s is required.%22, varname, value.getClass().getSimpleName(), type.getSimpleName()));%0A        %7D%0A%0A    protected %3CT%3E T getVariable(StepExecutionContext context, String varname, Class%3CT%3E type, T default_value) throws MuseExecutionError%0A        %7B%0A        Object value = context.getVariable(varname);%0A        if (value == null)%0A            return default_value;%0A        if (type.isAssignableFrom(value.getClass()))%0A            return (T) value;%0A        throw new MuseExecutionError(String.format(%22Variable '%25s' in the context is a %25s, but a %25s is required.%22, varname, value.getClass().getSimpleName(), type.getSimpleName()));%0A        %7D%0A%0A
     private 

add convience methods for getting variables of a specific type