package org.batfish.common; import java.util.function.BiFunction; import org.batfish.common.plugin.IBatfish; import org.batfish.common.util.BatfishObjectMapper; import org.batfish.common.util.JsonDiff; import org.batfish.datamodel.answers.AnswerElement; import org.batfish.datamodel.answers.JsonDiffAnswerElement; import org.batfish.datamodel.questions.Question; import org.codehaus.jettison.json.JSONException; import org.codehaus.jettison.json.JSONObject; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; public abstract class Answerer { public static Answerer create(Question question, IBatfish batfish) { String questionName = question.getName(); BiFunction<Question, IBatfish, Answerer> answererCreator = batfish .getAnswererCreators().get(questionName); if (answererCreator == null) { throw new BatfishException( "Cannot create answerer for missing question with name: " + questionName); } return answererCreator.apply(question, batfish); } protected final IBatfish _batfish; protected final BatfishLogger _logger; protected final Question _question; public Answerer(Question question, IBatfish batfish) { _batfish = batfish; _logger = batfish.getLogger(); _question = question; } public abstract AnswerElement answer(); // this is the default differential answerer // if you want a custom one for a subclass, override this function in the // subclass public AnswerElement answerDiff() { _batfish.pushBaseEnvironment(); _batfish.checkEnvironmentExists(); _batfish.popEnvironment(); _batfish.pushDeltaEnvironment(); _batfish.checkEnvironmentExists(); _batfish.popEnvironment(); _batfish.pushBaseEnvironment(); AnswerElement before = create(_question, _batfish).answer(); _batfish.popEnvironment(); _batfish.pushDeltaEnvironment(); AnswerElement after = create(_question, _batfish).answer(); _batfish.popEnvironment(); ObjectMapper mapper = new BatfishObjectMapper(); try { String beforeJsonStr = mapper.writeValueAsString(before); String afterJsonStr = mapper.writeValueAsString(after); JSONObject beforeJson = new JSONObject(beforeJsonStr); JSONObject afterJson = new JSONObject(afterJsonStr); JsonDiff diff = new JsonDiff(beforeJson, afterJson); return new JsonDiffAnswerElement(diff); } catch (JsonProcessingException | JSONException e) { throw new BatfishException( "Could not convert diff element to json string", e); } } }