private Change readChangeObject(JSONObject jsonChange) throws JSONException { JSONObject jsonFieldsChanged = jsonChange.getJSONObject("fields_changed"); List<FieldChange> fieldChanges = Lists.<Change.FieldChange>newArrayList(); for (Field field : Field.values()) { if (!jsonFieldsChanged.has(field.toString())) continue; JSONObject jsonFieldChange = jsonFieldsChanged.getJSONObject(field.toString()); switch (field) { case bugs_closed: String newBugs = CSV_JOINER.join(readStringArray(jsonFieldChange, "added")); String oldBugs = CSV_JOINER.join(readStringArray(jsonFieldChange, "removed")); fieldChanges.add(new FieldChange(field, null, newBugs, oldBugs, null, null)); break; case diff: JSONObject addedDiff = jsonFieldChange.getJSONObject("added"); fieldChanges.add( new FieldChange( field, new ObjectLink(addedDiff.getInt("id"), Diff.class), null, null, null, null)); break; // TODO unhandled case screenshots: case file_attachments: case target_groups: case target_people: continue; case status: fieldChanges.add( new FieldChange( field, null, ReviewRequestStatus.parseStatus(jsonFieldChange.getString("new")).toString(), ReviewRequestStatus.parseStatus(jsonFieldChange.getString("old")).toString(), null, null)); break; case summary: case description: case testing_done: case branch: fieldChanges.add( new FieldChange( field, null, jsonFieldChange.getString("new"), jsonFieldChange.getString("old"), null, null)); break; default: ReviewboardCorePlugin.getDefault() .log( IStatus.WARNING, "Could not parse change due to unhandled field with name " + field.toString()); continue; } } return new Change( jsonChange.getInt("id"), jsonChange.getString("text"), ReviewboardUtil.marshallDate(jsonChange.getString("timestamp")), fieldChanges); }