public DiffData readDiffData(String source) throws ReviewboardException { try { JSONObject jsonDiffData = checkedGetJSonRootObject(source).getJSONObject("diff_data"); DiffData diffData = new DiffData(); diffData.setBinary(jsonDiffData.getBoolean("binary")); diffData.setNewFile(jsonDiffData.getBoolean("new_file")); diffData.setNumChanges(jsonDiffData.getInt("num_changes")); JSONArray changedChunkIndexes = jsonDiffData.getJSONArray("changed_chunk_indexes"); for (int i = 0; i < changedChunkIndexes.length(); i++) diffData.getChangedChunkIndexes().add(changedChunkIndexes.getInt(i)); JSONArray chunks = jsonDiffData.getJSONArray("chunks"); for (int i = 0; i < chunks.length(); i++) { JSONObject jsonChunk = chunks.getJSONObject(i); Chunk chunk = new Chunk(); chunk.setChange(Type.fromString(jsonChunk.getString("change"))); chunk.setCollapsable(jsonChunk.getBoolean("collapsable")); chunk.setIndex(jsonChunk.getInt("index")); chunk.setNumLines(jsonChunk.getInt("numlines")); JSONArray lines = jsonChunk.getJSONArray("lines"); for (int j = 0; j < lines.length(); j++) { JSONArray lineArray = lines.getJSONArray(j); Line line = new Line(); line.setDiffRowNumber(lineArray.getInt(0)); line.setLeftFileRowNumber(getPossiblyEmptyInt(lineArray, 1)); line.setLeftLineText(lineArray.getString(2)); line.setRightFileRowNumber(getPossiblyEmptyInt(lineArray, 4)); line.setRightLineText(lineArray.getString(5)); line.setWhitespaceOnly(lineArray.getBoolean(7)); chunk.getLines().add(line); } diffData.getChunks().add(chunk); } return diffData; } catch (JSONException e) { throw new ReviewboardException(e.getMessage(), e); } }
/** * Get all data required to create a diff view wrt. to this request in one go. * * @return an instance with just enough information to render a sufficient view. If not all * required parameters were given either they are supplemented with reasonable defaults if * possible, otherwise the related field(s) are {@code null}. {@link DiffData#errorMsg} {@code * != null} indicates, that an error occured and one should not try to render a view. */ public DiffData getDiffData() { DiffData data = new DiffData(); data.path = getPath().substring(0, path.lastIndexOf('/')); data.filename = Util.htmlize(getResourceFile().getName()); String srcRoot = getSourceRootPath(); String context = req.getContextPath(); String[] filepath = new String[2]; data.rev = new String[2]; data.file = new String[2][]; data.param = new String[2]; /* * Basically the request URI looks like this: * http://$site/$webapp/diff/$resourceFile?r1=$fileA@$revA&r2=$fileB@$revB * The code below extracts file path and revision from the URI. */ for (int i = 1; i <= 2; i++) { String[] tmp = null; String p = req.getParameter("r" + i); if (p != null) { tmp = p.split("@"); } if (tmp != null && tmp.length == 2) { filepath[i - 1] = tmp[0]; data.rev[i - 1] = tmp[1]; } } if (data.rev[0] == null || data.rev[1] == null || data.rev[0].length() == 0 || data.rev[1].length() == 0 || data.rev[0].equals(data.rev[1])) { data.errorMsg = "Please pick two revisions to compare the changed " + "from the <a href=\"" + context + Prefix.HIST_L + getUriEncodedPath() + "\">history</a>"; return data; } data.genre = AnalyzerGuru.getGenre(getResourceFile().getName()); if (data.genre == null || txtGenres.contains(data.genre)) { InputStream[] in = new InputStream[2]; try { // Get input stream for both older and newer file. for (int i = 0; i < 2; i++) { File f = new File(srcRoot + filepath[i]); in[i] = HistoryGuru.getInstance().getRevision(f.getParent(), f.getName(), data.rev[i]); if (in[i] == null) { data.errorMsg = "Unable to get revision " + Util.htmlize(data.rev[i]) + " for file: " + Util.htmlize(getPath()); return data; } } /* * If the genre of the older revision cannot be determined, * (this can happen if the file was empty), try with newer * version. */ for (int i = 0; i < 2 && data.genre == null; i++) { try { data.genre = AnalyzerGuru.getGenre(in[i]); } catch (IOException e) { data.errorMsg = "Unable to determine the file type: " + Util.htmlize(e.getMessage()); } } if (data.genre != Genre.PLAIN && data.genre != Genre.HTML) { return data; } ArrayList<String> lines = new ArrayList<>(); Project p = getProject(); for (int i = 0; i < 2; i++) { try (BufferedReader br = new BufferedReader(ExpandTabsReader.wrap(new InputStreamReader(in[i]), p))) { String line; while ((line = br.readLine()) != null) { lines.add(line); } data.file[i] = lines.toArray(new String[lines.size()]); lines.clear(); } in[i] = null; } } catch (Exception e) { data.errorMsg = "Error reading revisions: " + Util.htmlize(e.getMessage()); } finally { for (int i = 0; i < 2; i++) { IOUtils.close(in[i]); } } if (data.errorMsg != null) { return data; } try { data.revision = Diff.diff(data.file[0], data.file[1]); } catch (DifferentiationFailedException e) { data.errorMsg = "Unable to get diffs: " + Util.htmlize(e.getMessage()); } for (int i = 0; i < 2; i++) { try { URI u = new URI(null, null, null, filepath[i] + "@" + data.rev[i], null); data.param[i] = u.getRawQuery(); } catch (URISyntaxException e) { LOGGER.log(Level.WARNING, "Failed to create URI: ", e); } } data.full = fullDiff(); data.type = getDiffType(); } return data; }