package gherkin.parser; import gherkin.formatter.Formatter; import gherkin.formatter.model.Background; import gherkin.formatter.model.Builder; import gherkin.formatter.model.Comment; import gherkin.formatter.model.DocString; import gherkin.formatter.model.Examples; import gherkin.formatter.model.Feature; import gherkin.formatter.model.Scenario; import gherkin.formatter.model.ScenarioOutline; import gherkin.formatter.model.Step; import gherkin.formatter.model.Tag; import gherkin.lexer.Listener; import java.util.ArrayList; import java.util.List; public class FormatterListener implements Listener { private final Formatter formatter; private Stash stash; private Builder currentBuilder; private class Stash { private List<Comment> comments; private List<Tag> tags; private String featureId; private String featureElementId; private String examplesId; private int rowIndex = 0; public void comment(Comment comment) { comments.add(comment); } public void tag(Tag tag) { tags.add(tag); } public void reset() { comments = new ArrayList<Comment>(); tags = new ArrayList<Tag>(); } public String featureId(String name) { return featureId = id(name); } public String featureElementId(String name) { return featureElementId = featureId + ";" + id(name); } public String examplesId(String name) { rowIndex = 0; return examplesId = featureElementId + ";" + id(name); } private String id(String name) { return name.replaceAll("[\\s_]", "-").toLowerCase(); } public String nextExampleId() { rowIndex++; return "" + examplesId + ";" + rowIndex; } } public FormatterListener(Formatter formatter) { this.formatter = formatter; stash = new Stash(); stash.reset(); } @Override public void comment(String comment, Integer line) { stash.comment(new Comment(comment, line)); } @Override public void tag(String tag, Integer line) { stash.tag(new Tag(tag, line)); } @Override public void feature(String keyword, String name, String description, Integer line) { formatter.feature(new Feature(stash.comments, stash.tags, keyword, name, description, line, stash.featureId(name))); stash.reset(); } @Override public void background(String keyword, String name, String description, Integer line) { formatter.background(new Background(stash.comments, keyword, name, description, line)); stash.reset(); } @Override public void scenario(String keyword, String name, String description, Integer line) { replayStepsOrExamples(); formatter.scenario(new Scenario(stash.comments, stash.tags, keyword, name, description, line, stash.featureElementId(name))); stash.reset(); } @Override public void scenarioOutline(String keyword, String name, String description, Integer line) { replayStepsOrExamples(); formatter.scenarioOutline(new ScenarioOutline(stash.comments, stash.tags, keyword, name, description, line, stash.featureElementId(name))); stash.reset(); } @Override public void examples(String keyword, String name, String description, Integer line) { replayStepsOrExamples(); currentBuilder = new Examples.Builder(stash.comments, stash.tags, keyword, name, description, line, stash.examplesId(name)); stash.reset(); } @Override public void step(String keyword, String name, Integer line) { replayStepsOrExamples(); currentBuilder = new Step.Builder(stash.comments, keyword, name, line); stash.reset(); } @Override public void row(List<String> cells, Integer line) { currentBuilder.row(stash.comments, cells, line, stash.nextExampleId()); stash.reset(); } @Override public void docString(String contentType, String content, Integer line) { currentBuilder.docString(new DocString(contentType, content, line)); } @Override public void eof() { replayStepsOrExamples(); formatter.eof(); } /** * Not part of the API. Used for testing only. */ public void syntaxError(String state, String event, List<String> legalEvents, String uri, Integer line) { formatter.syntaxError(state, event, legalEvents, uri, line); } private void replayStepsOrExamples() { if (currentBuilder != null) { currentBuilder.replay(formatter); currentBuilder = null; } } }