package fr.inria.diversify.persistence.json.input; import com.fasterxml.uuid.Generators; import fr.inria.diversify.codeFragment.CodeFragment; import fr.inria.diversify.diversification.InputProgram; import fr.inria.diversify.persistence.PersistenceException; import fr.inria.diversify.transformation.Transformation; import org.json.JSONException; import org.json.JSONObject; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.UUID; import static fr.inria.diversify.persistence.json.output.JsonSectionOutput.*; /** * Created by marodrig on 12/01/2015. */ public abstract class JsonTransformationInput extends JsonSectionInput { private Map<Integer, String> failures; public JsonTransformationInput(InputProgram inputProgram) { super(inputProgram, null); } public JsonTransformationInput(InputProgram inputProgram, JSONObject jsonObject) { super(inputProgram, jsonObject); } protected abstract Transformation build(); /** * Prepend the error message with the transformation index * * @param transf Transformation * @param s Error message * @return */ protected String getTransformationErrorString(Transformation transf, String s) { if (transf != null) return "Transformation " + transf.getIndex() + " " + s; return s; } /** * Log the status of the JSON loading of a Code fragment for a transformation * * @param ast * @param cf * @param src * @param pos */ protected void logCfStatus(Transformation ast, CodeFragment cf, String pos, String src) { StringBuilder sb = new StringBuilder(""); if (ast != null) sb.append("Transf ").append(ast.getIndex()).append(". "); if (cf == null) { sb.append("Unable to find code fragment \"").append(src).append("\" at \"").append(pos).append("\""); String s = sb.toString(); throwError(s, null, true); } else { if (!cf.positionString().equals(pos)) { sb.append("Position mismatch -> Storage: \"").append(pos).append("\"; Found: \""). append(cf.positionString()).append("\"."); throwWarning(sb.toString(), null, false); } if (!cf.equalString().equals(src)) { sb = new StringBuilder(""); if (ast != null) sb.append("Transf ").append(ast.getIndex()).append(". "); sb.append("Source mismatch -> Storage: \"").append(src). append("\"; Found: \"").append(cf.equalString()).append("\"."); throwWarning(sb.toString(), null, false); } } } /** * Takes a string and returns a valid UUI from the string if such string is a valid * UUI. Otherwise, generates a new UUI * * @param uuid * @return */ private UUID getValidUUI(String uuid) { if (uuid == null) return Generators.timeBasedGenerator().generate(); try { UUID fromStringUUID = UUID.fromString(uuid); String toStringUUID = fromStringUUID.toString(); if (toStringUUID.equals(uuid)) return fromStringUUID; } catch (IllegalArgumentException e) { return Generators.timeBasedGenerator().generate(); } return Generators.timeBasedGenerator().generate(); } /** * gets data from the JSON object into the transformation object */ protected Transformation get(Map<UUID, Transformation> t) throws JSONException { // HashMap<Integer, String> failures = getFailures(); UUID index = getValidUUI(getJsonObject().getString(TINDEX)); Transformation astt; if (t.containsKey(index)) { astt = t.get(index); } else { astt = build(); astt.setIndex(index); astt.setStatus(getJsonObject().getInt(STATUS)); } return astt; } /** * Adds the transformation to the transformation's dictionary * * @param t Transformation's dictionary * @param astt AST Transformation */ protected void addTransformation(Map<UUID, Transformation> t, Transformation astt) { t.put(astt.getIndex(), astt); } /** * Put the transformation after the reading is properly done * * @param transformation */ protected void putTransformation(Transformation transformation) { } @Override public void read(Map<UUID, Transformation> transformations) { try { get(transformations); } catch (JSONException e) { throw new PersistenceException("Unable to map JSON into transformation", e); } } protected Map<String, String> getVarMap(JSONObject jsonObject) throws JSONException { Map<String, String> varMap = new HashMap<>(); Iterator<String> nameItr = jsonObject.keys(); while (nameItr.hasNext()) { String name = nameItr.next(); varMap.put(name, jsonObject.getString(name)); } return varMap; } /** * Indicate if can handle a section within the file * * @param s Section name * @return True if can handle */ public abstract boolean canRead(String s); /** * Failures dictionary * * @return The failures dictionary */ public Map<Integer, String> getFailures() { return failures; } public void setFailures(Map<Integer, String> failures) { this.failures = failures; } }