package nl.hsac.fitnesse.fixture.slim;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * Fixture to generate strings using Freemarker templates. These strings can be stored in variables so the can
 * be passed as arguments to methods of other fixtures.
 * This fixture can be used using Slim's dynamic decision tables or using scripts (and scenarios).
 */
public class FreemarkerFixture extends SlimFixture {
    private final String defaultTemplate;

    private final Map<String, Object> currentValues = new LinkedHashMap<String, Object>();

    /**
     * Creates new without default template.
     */
    public FreemarkerFixture() {
        this(null);
    }

    /**
     * Creates new with a default template, this is used in dynamic decision tables to prevent having to specify
     * the template in the header row (any output column just gets the result of applying this templates).
     * @param defaultTemplate location (below /templates/) of Freemarker template.
     */
    public FreemarkerFixture(String defaultTemplate) {
        this.defaultTemplate = defaultTemplate;
    }

    /**
     * Applies template to current values.
     * @param aTemplate name of template file (relative to 'testdata' directory on classpath)
     * @return template result.
     */
    public String applyTemplate(String aTemplate) {
        String result = getEnvironment().processTemplate(aTemplate, currentValues);
        try {
            if (aTemplate.contains(".xml")) {
                result = getEnvironment().getHtmlForXml(result);
            } else if (aTemplate.contains(".json")) {
                result = getEnvironment().getHtmlForJson(result);
            }
        } catch (Exception e) {
            // can not be formatted, return raw result
        }
        return result;
    }

    /**
     * Stores value to be passed to template, or GET.
     * @param value value to be passed.
     * @param name name to use this value for.
     */
    public void setValueFor(Object value, String name) {
        String cleanName = cleanupValue(name);
        Object cleanValue = value;
        if (value instanceof String) {
            cleanupValue((String) value);
        }
        currentValues.put(cleanName, cleanValue);
    }

    /**
     * Stores list of values to be passed to template.
     * @param values comma separated list of values.
     * @param name name to use this list for.
     */
    public void setValuesFor(String values, String name) {
        String cleanName = cleanupValue(name);
        String[] valueArrays = values.split("\\s*,\\s*");
        for (int i = 0; i < valueArrays.length; i++) {
            valueArrays[i] = cleanupValue(valueArrays[i]);
        }
        currentValues.put(cleanName, valueArrays);
    }

    /**
     * Clears a values previously set.
     * @param name value to remove.
     * @return true if value was present.
     */
    public boolean clearValue(String name) {
        String cleanName = cleanupValue(name);
        boolean result = currentValues.containsKey(cleanName);
        currentValues.remove(cleanName);
        return result;
    }

    /**
     * Clears all values previously set.
     */
    public void clearValues() {
        currentValues.clear();
    }

    // methods to support usage in dynamic decision tables
    public void reset() {
        clearValues();
    }

    public void set(String key, Object value) {
        setValueFor(value, key);
    }

    public String get(String requestedValue) {
        String result;
        if (defaultTemplate == null) {
            result = applyTemplate(requestedValue);
        } else {
            result = applyTemplate(defaultTemplate);
        }
        return result;
    }

}

@@ -37,63 +37,8 @@
 m;%0A%0A
-import java.util.LinkedHashMap;%0Aimport java.util.Map;%0A%0A
 /**%0A
@@ -357,16 +357,23 @@
 mFixture
+WithMap
  %7B%0A    p
@@ -414,100 +414,8 @@
 e;%0A%0A
-    private final Map%3CString, Object%3E currentValues = new LinkedHashMap%3CString, Object%3E();%0A%0A
     
@@ -1265,17 +1265,20 @@
 mplate, 
-c
+getC
 urrentVa
@@ -1281,16 +1281,18 @@
 ntValues
+()
 );%0A     
@@ -1681,1650 +1681,63 @@
    /
-**%0A     * Stores value to be passed to template, or GET.%0A     * @param value value to be passed.%0A     * @param name name to use this value for.%0A     */%0A    public void setValueFor(Object value, String name) %7B%0A        String cleanName = cleanupValue(name);%0A        Object cleanValue = value;%0A        if (value instanceof String) %7B%0A            cleanupValue((String) value);%0A        %7D%0A        currentValues.put(cleanName, cleanValue);%0A    %7D%0A%0A    /**%0A     * Stores list of values to be passed to template.%0A     * @param values comma separated list of values.%0A     * @param name name to use this list for.%0A     */%0A    public void setValuesFor(String values, String name) %7B%0A        String cleanName = cleanupValue(name);%0A        String%5B%5D valueArrays = values.split(%22%5C%5Cs*,%5C%5Cs*%22);%0A        for (int i = 0; i %3C valueArrays.length; i++) %7B%0A            valueArrays%5Bi%5D = cleanupValue(valueArrays%5Bi%5D);%0A        %7D%0A        currentValues.put(cleanName, valueArrays);%0A    %7D%0A%0A    /**%0A     * Clears a values previously set.%0A     * @param name value to remove.%0A     * @return true if value was present.%0A     */%0A    public boolean clearValue(String name) %7B%0A        String cleanName = cleanupValue(name);%0A        boolean result = currentValues.containsKey(cleanName);%0A        currentValues.remove(cleanName);%0A        return result;%0A    %7D%0A%0A    /**%0A     * Clears all values previously set.%0A     */%0A    public void clearValues() %7B%0A        currentValues.clear();%0A    %7D%0A%0A    // methods to support usage in dynamic decision tables%0A    public void reset() %7B%0A        clearValues();%0A    %7D%0A%0A    public void set(String key, Object value) %7B%0A        setValueFor(value, key);%0A    %7D
+/// methods to support usage in dynamic decision tables
 %0A%0A  
@@ -2005,10 +2005,76 @@
 %0A    %7D%0A%0A
+    //// end: methods to support usage in dynamic decision tables%0A
 %7D%0A

Simplify FreemarkerFixture using new base class