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);
    }
  }
Exemplo n.º 2
0
  /**
   * 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;
  }