package org.jboss.windup.reporting.freemarker;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import org.jboss.forge.furnace.Furnace;
import org.jboss.windup.config.GraphRewrite;
import org.jboss.windup.config.Variables;
import org.jboss.windup.config.operation.GraphOperation;
import org.jboss.windup.reporting.service.ReportService;
import org.jboss.windup.util.exception.WindupException;
import org.ocpsoft.rewrite.context.EvaluationContext;
import freemarker.template.Template;
import freemarker.template.TemplateException;
/**
* This class is used to produce a freemarker report (and the associated ReportModel) from outside of an Iteration context.
*
* @author <a href="mailto:jesse.sightler@gmail.com">Jesse Sightler</a> <jesse.sightler@gmail.com)
*
*/
public class FreeMarkerOperation extends GraphOperation
{
private static final Logger LOG = Logger.getLogger(FreeMarkerOperation.class.getName());
private final Furnace furnace;
private final String templatePath;
private final String outputFilename;
private List<String> variableNames = new ArrayList<>();
protected FreeMarkerOperation(Furnace furnace, String templatePath, String outputFilename, String... varNames)
{
this.furnace = furnace;
this.templatePath = templatePath.replace('\\', '/');
this.outputFilename = outputFilename;
this.variableNames = Arrays.asList(varNames);
}
/**
* Create a FreeMarkerOperation with the provided furnace instance template path, and varNames.
*
* The variables in varNames will be provided to the template, and a new ReportModel will be created with these variables attached.
*/
public static FreeMarkerOperation create(Furnace furnace, String templatePath, String outputFilename,
String... varNames)
{
return new FreeMarkerOperation(furnace, templatePath, outputFilename, varNames);
}
@Override
public void perform(GraphRewrite event, EvaluationContext context)
{
try
{
ReportService reportService = new ReportService(event.getGraphContext());
Path outputDir = reportService.getReportDirectory();
Path outputPath = outputDir.resolve(outputFilename);
LOG.info("Reporting: Writing template \"" + templatePath + "\" to output file \""
+ outputPath.toAbsolutePath().toString() + "\"");
freemarker.template.Configuration freemarkerConfig = FreeMarkerUtil.getDefaultFreemarkerConfiguration();
Template template = freemarkerConfig.getTemplate(templatePath);
Variables varStack = Variables.instance(event);
// just the variables
Map<String, Object> vars = FreeMarkerUtil.findFreeMarkerContextVariables(varStack,
variableNames.toArray(new String[variableNames.size()]));
vars.put("event", event);
// also, extension functions
Map<String, Object> freeMarkerExtensions = FreeMarkerUtil.findFreeMarkerExtensions(furnace, event);
Map<String, Object> objects = new HashMap<>(vars);
objects.putAll(freeMarkerExtensions);
try (FileWriter fw = new FileWriter(outputPath.toFile()))
{
template.process(objects, fw);
}
}
catch (IOException e)
{
throw new WindupException("Failed to write template results due to: " + e.getMessage(), e);
}
catch (TemplateException e)
{
throw new WindupException("FreeMarkerOperation TemplateException: " + e.getMessage(), e);
}
}
@Override
public String toString()
{
return "FreeMarkerOperation[template=" + templatePath + ", output=" + outputFilename + "]";
}
}