Require getting ChangeJson through a factory

The ChangeJson object is not thread safe.  It internally has a mutable
options array and tracks information about accounts in a local cache.

RestViews keep reusing this object in @Singleton views in a way that
is not thread safe.

Change the API to require obtaining the ChangeJson from a Factory
after passing in the Set<ListChangeOptions> the caller wants to use.

Change-Id: I2167b909fd52c10565fc232aefb2f1d27c65c8de
This commit is contained in:
Shawn Pearce
2015-07-17 20:50:04 -07:00
parent 2efa6030fd
commit ba24004f70
15 changed files with 87 additions and 75 deletions

View File

@@ -81,7 +81,7 @@ class ChangeApiImpl implements ChangeApi {
private final GetTopic getTopic; private final GetTopic getTopic;
private final PutTopic putTopic; private final PutTopic putTopic;
private final PostReviewers postReviewers; private final PostReviewers postReviewers;
private final Provider<ChangeJson> changeJson; private final ChangeJson.Factory changeJson;
private final PostHashtags postHashtags; private final PostHashtags postHashtags;
private final GetHashtags getHashtags; private final GetHashtags getHashtags;
private final ListChangeComments listComments; private final ListChangeComments listComments;
@@ -102,7 +102,7 @@ class ChangeApiImpl implements ChangeApi {
GetTopic getTopic, GetTopic getTopic,
PutTopic putTopic, PutTopic putTopic,
PostReviewers postReviewers, PostReviewers postReviewers,
Provider<ChangeJson> changeJson, ChangeJson.Factory changeJson,
PostHashtags postHashtags, PostHashtags postHashtags,
GetHashtags getHashtags, GetHashtags getHashtags,
ListChangeComments listComments, ListChangeComments listComments,
@@ -276,7 +276,7 @@ class ChangeApiImpl implements ChangeApi {
if (u.isIdentifiedUser()) { if (u.isIdentifiedUser()) {
((IdentifiedUser) u).clearStarredChanges(); ((IdentifiedUser) u).clearStarredChanges();
} }
return changeJson.get().addOptions(s).format(change); return changeJson.create(s).format(change);
} catch (OrmException e) { } catch (OrmException e) {
throw new RestApiException("Cannot retrieve change", e); throw new RestApiException("Cannot retrieve change", e);
} }

View File

@@ -53,7 +53,7 @@ public class Abandon implements RestModifyView<ChangeResource, AbandonInput>,
private final ChangeHooks hooks; private final ChangeHooks hooks;
private final AbandonedSender.Factory abandonedSenderFactory; private final AbandonedSender.Factory abandonedSenderFactory;
private final Provider<ReviewDb> dbProvider; private final Provider<ReviewDb> dbProvider;
private final ChangeJson json; private final ChangeJson.Factory json;
private final ChangeIndexer indexer; private final ChangeIndexer indexer;
private final ChangeUpdate.Factory updateFactory; private final ChangeUpdate.Factory updateFactory;
private final ChangeMessagesUtil cmUtil; private final ChangeMessagesUtil cmUtil;
@@ -62,7 +62,7 @@ public class Abandon implements RestModifyView<ChangeResource, AbandonInput>,
Abandon(ChangeHooks hooks, Abandon(ChangeHooks hooks,
AbandonedSender.Factory abandonedSenderFactory, AbandonedSender.Factory abandonedSenderFactory,
Provider<ReviewDb> dbProvider, Provider<ReviewDb> dbProvider,
ChangeJson json, ChangeJson.Factory json,
ChangeIndexer indexer, ChangeIndexer indexer,
ChangeUpdate.Factory updateFactory, ChangeUpdate.Factory updateFactory,
ChangeMessagesUtil cmUtil) { ChangeMessagesUtil cmUtil) {
@@ -90,8 +90,7 @@ public class Abandon implements RestModifyView<ChangeResource, AbandonInput>,
throw new ResourceConflictException("draft changes cannot be abandoned"); throw new ResourceConflictException("draft changes cannot be abandoned");
} }
change = abandon(control, input.message, caller.getAccount()); change = abandon(control, input.message, caller.getAccount());
ChangeInfo result = json.format(change); return json.create(ChangeJson.NO_OPTIONS).format(change);
return result;
} }
public Change abandon(ChangeControl control, public Change abandon(ChangeControl control,

View File

@@ -98,8 +98,9 @@ import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.query.change.ChangeData.ChangedLines; import com.google.gerrit.server.query.change.ChangeData.ChangedLines;
import com.google.gerrit.server.query.change.QueryResult; import com.google.gerrit.server.query.change.QueryResult;
import com.google.gwtorm.server.OrmException; import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Provider; import com.google.inject.Provider;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.assistedinject.AssistedInject;
import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.Repository;
@@ -122,6 +123,12 @@ import java.util.TreeMap;
public class ChangeJson { public class ChangeJson {
private static final Logger log = LoggerFactory.getLogger(ChangeJson.class); private static final Logger log = LoggerFactory.getLogger(ChangeJson.class);
public static final Set<ListChangesOption> NO_OPTIONS =
Collections.emptySet();
public interface Factory {
ChangeJson create(Set<ListChangesOption> options);
}
private final Provider<ReviewDb> db; private final Provider<ReviewDb> db;
private final LabelNormalizer labelNormalizer; private final LabelNormalizer labelNormalizer;
@@ -145,7 +152,7 @@ public class ChangeJson {
private AccountLoader accountLoader; private AccountLoader accountLoader;
private FixInput fix; private FixInput fix;
@Inject @AssistedInject
ChangeJson( ChangeJson(
Provider<ReviewDb> db, Provider<ReviewDb> db,
LabelNormalizer ln, LabelNormalizer ln,
@@ -163,7 +170,8 @@ public class ChangeJson {
WebLinks webLinks, WebLinks webLinks,
ChangeMessagesUtil cmUtil, ChangeMessagesUtil cmUtil,
Provider<ConsistencyChecker> checkerProvider, Provider<ConsistencyChecker> checkerProvider,
ActionJson actionJson) { ActionJson actionJson,
@Assisted Set<ListChangesOption> options) {
this.db = db; this.db = db;
this.labelNormalizer = ln; this.labelNormalizer = ln;
this.userProvider = user; this.userProvider = user;
@@ -181,17 +189,9 @@ public class ChangeJson {
this.cmUtil = cmUtil; this.cmUtil = cmUtil;
this.checkerProvider = checkerProvider; this.checkerProvider = checkerProvider;
this.actionJson = actionJson; this.actionJson = actionJson;
options = EnumSet.noneOf(ListChangesOption.class); this.options = options.isEmpty()
} ? EnumSet.noneOf(ListChangesOption.class)
: EnumSet.copyOf(options);
public ChangeJson addOption(ListChangesOption o) {
options.add(o);
return this;
}
public ChangeJson addOptions(Collection<ListChangesOption> o) {
options.addAll(o);
return this;
} }
public ChangeJson fix(FixInput fix) { public ChangeJson fix(FixInput fix) {

View File

@@ -25,19 +25,20 @@ import com.google.gerrit.server.project.ChangeControl;
import com.google.gwtorm.server.OrmException; import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject; import com.google.inject.Inject;
import java.util.EnumSet;
public class Check implements RestReadView<ChangeResource>, public class Check implements RestReadView<ChangeResource>,
RestModifyView<ChangeResource, FixInput> { RestModifyView<ChangeResource, FixInput> {
private final ChangeJson json; private final ChangeJson.Factory jsonFactory;
@Inject @Inject
Check(ChangeJson json) { Check(ChangeJson.Factory json) {
this.json = json; this.jsonFactory = json;
json.addOption(ListChangesOption.CHECK);
} }
@Override @Override
public Response<ChangeInfo> apply(ChangeResource rsrc) throws OrmException { public Response<ChangeInfo> apply(ChangeResource rsrc) throws OrmException {
return Response.withMustRevalidate(json.format(rsrc)); return Response.withMustRevalidate(newChangeJson().format(rsrc));
} }
@Override @Override
@@ -49,6 +50,10 @@ public class Check implements RestReadView<ChangeResource>,
&& !ctl.getCurrentUser().getCapabilities().canMaintainServer()) { && !ctl.getCurrentUser().getCapabilities().canMaintainServer()) {
throw new AuthException("Cannot fix change"); throw new AuthException("Cannot fix change");
} }
return Response.withMustRevalidate(json.fix(input).format(rsrc)); return Response.withMustRevalidate(newChangeJson().fix(input).format(rsrc));
}
private ChangeJson newChangeJson() {
return jsonFactory.create(EnumSet.of(ListChangesOption.CHECK));
} }
} }

View File

@@ -43,12 +43,12 @@ public class CherryPick implements RestModifyView<RevisionResource, CherryPickIn
UiAction<RevisionResource> { UiAction<RevisionResource> {
private final Provider<ReviewDb> dbProvider; private final Provider<ReviewDb> dbProvider;
private final CherryPickChange cherryPickChange; private final CherryPickChange cherryPickChange;
private final ChangeJson json; private final ChangeJson.Factory json;
@Inject @Inject
CherryPick(Provider<ReviewDb> dbProvider, CherryPick(Provider<ReviewDb> dbProvider,
CherryPickChange cherryPickChange, CherryPickChange cherryPickChange,
ChangeJson json) { ChangeJson.Factory json) {
this.dbProvider = dbProvider; this.dbProvider = dbProvider;
this.cherryPickChange = cherryPickChange; this.cherryPickChange = cherryPickChange;
this.json = json; this.json = json;
@@ -84,7 +84,7 @@ public class CherryPick implements RestModifyView<RevisionResource, CherryPickIn
cherryPickChange.cherryPick(revision.getChange(), cherryPickChange.cherryPick(revision.getChange(),
revision.getPatchSet(), input.message, refName, revision.getPatchSet(), input.message, refName,
refControl); refControl);
return json.format(cherryPickedChangeId); return json.create(ChangeJson.NO_OPTIONS).format(cherryPickedChangeId);
} catch (InvalidChangeOperationException e) { } catch (InvalidChangeOperationException e) {
throw new BadRequestException(e.getMessage()); throw new BadRequestException(e.getMessage());
} catch (MergeException e) { } catch (MergeException e) {

View File

@@ -85,7 +85,7 @@ public class CreateChange implements
private final ProjectsCollection projectsCollection; private final ProjectsCollection projectsCollection;
private final CommitValidators.Factory commitValidatorsFactory; private final CommitValidators.Factory commitValidatorsFactory;
private final ChangeInserter.Factory changeInserterFactory; private final ChangeInserter.Factory changeInserterFactory;
private final ChangeJson json; private final ChangeJson.Factory jsonFactory;
private final ChangeUtil changeUtil; private final ChangeUtil changeUtil;
private final boolean allowDrafts; private final boolean allowDrafts;
@@ -97,7 +97,7 @@ public class CreateChange implements
ProjectsCollection projectsCollection, ProjectsCollection projectsCollection,
CommitValidators.Factory commitValidatorsFactory, CommitValidators.Factory commitValidatorsFactory,
ChangeInserter.Factory changeInserterFactory, ChangeInserter.Factory changeInserterFactory,
ChangeJson json, ChangeJson.Factory json,
ChangeUtil changeUtil, ChangeUtil changeUtil,
@GerritServerConfig Config config) { @GerritServerConfig Config config) {
this.db = db; this.db = db;
@@ -107,7 +107,7 @@ public class CreateChange implements
this.projectsCollection = projectsCollection; this.projectsCollection = projectsCollection;
this.commitValidatorsFactory = commitValidatorsFactory; this.commitValidatorsFactory = commitValidatorsFactory;
this.changeInserterFactory = changeInserterFactory; this.changeInserterFactory = changeInserterFactory;
this.json = json; this.jsonFactory = json;
this.changeUtil = changeUtil; this.changeUtil = changeUtil;
this.allowDrafts = config.getBoolean("change", "allowDrafts", true); this.allowDrafts = config.getBoolean("change", "allowDrafts", true);
} }
@@ -219,6 +219,7 @@ public class CreateChange implements
ins.setGroups(groups); ins.setGroups(groups);
ins.insert(); ins.insert();
ChangeJson json = jsonFactory.create(ChangeJson.NO_OPTIONS);
return Response.created(json.format(change.getId())); return Response.created(json.format(change.getId()));
} }
} }

View File

@@ -23,30 +23,34 @@ import com.google.inject.Inject;
import org.kohsuke.args4j.Option; import org.kohsuke.args4j.Option;
import java.util.EnumSet;
public class GetChange implements RestReadView<ChangeResource> { public class GetChange implements RestReadView<ChangeResource> {
private final ChangeJson json; private final ChangeJson.Factory json;
private final EnumSet<ListChangesOption> options =
EnumSet.noneOf(ListChangesOption.class);
@Option(name = "-o", usage = "Output options") @Option(name = "-o", usage = "Output options")
void addOption(ListChangesOption o) { void addOption(ListChangesOption o) {
json.addOption(o); options.add(o);
} }
@Option(name = "-O", usage = "Output option flags, in hex") @Option(name = "-O", usage = "Output option flags, in hex")
void setOptionFlagsHex(String hex) { void setOptionFlagsHex(String hex) {
json.addOptions(ListChangesOption.fromBits(Integer.parseInt(hex, 16))); options.addAll(ListChangesOption.fromBits(Integer.parseInt(hex, 16)));
} }
@Inject @Inject
GetChange(ChangeJson json) { GetChange(ChangeJson.Factory json) {
this.json = json; this.json = json;
} }
@Override @Override
public Response<ChangeInfo> apply(ChangeResource rsrc) throws OrmException { public Response<ChangeInfo> apply(ChangeResource rsrc) throws OrmException {
return Response.withMustRevalidate(json.format(rsrc)); return Response.withMustRevalidate(json.create(options).format(rsrc));
} }
Response<ChangeInfo> apply(RevisionResource rsrc) throws OrmException { Response<ChangeInfo> apply(RevisionResource rsrc) throws OrmException {
return Response.withMustRevalidate(json.format(rsrc)); return Response.withMustRevalidate(json.create(options).format(rsrc));
} }
} }

View File

@@ -33,14 +33,13 @@ import java.util.concurrent.TimeUnit;
public class GetCommit implements RestReadView<RevisionResource> { public class GetCommit implements RestReadView<RevisionResource> {
private final GitRepositoryManager repoManager; private final GitRepositoryManager repoManager;
private final ChangeJson json; private final ChangeJson.Factory json;
@Option(name = "--links", usage = "Add weblinks") @Option(name = "--links", usage = "Add weblinks")
private boolean addLinks; private boolean addLinks;
@Inject @Inject
GetCommit(GitRepositoryManager repoManager, GetCommit(GitRepositoryManager repoManager, ChangeJson.Factory json) {
ChangeJson json) {
this.repoManager = repoManager; this.repoManager = repoManager;
this.json = json; this.json = json;
} }
@@ -53,8 +52,9 @@ public class GetCommit implements RestReadView<RevisionResource> {
String rev = rsrc.getPatchSet().getRevision().get(); String rev = rsrc.getPatchSet().getRevision().get();
RevCommit commit = rw.parseCommit(ObjectId.fromString(rev)); RevCommit commit = rw.parseCommit(ObjectId.fromString(rev));
rw.parseBody(commit); rw.parseBody(commit);
Response<CommitInfo> r = Response.ok( CommitInfo info = json.create(ChangeJson.NO_OPTIONS)
json.toCommit(rsrc.getControl(), rw, commit, addLinks)); .toCommit(rsrc.getControl(), rw, commit, addLinks);
Response<CommitInfo> r = Response.ok(info);
if (rsrc.isCacheable()) { if (rsrc.isCacheable()) {
r.caching(CacheControl.PRIVATE(7, TimeUnit.DAYS)); r.caching(CacheControl.PRIVATE(7, TimeUnit.DAYS));
} }

View File

@@ -47,28 +47,29 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.io.IOException; import java.io.IOException;
import java.util.EnumSet;
@Singleton @Singleton
public class Rebase implements RestModifyView<RevisionResource, RebaseInput>, public class Rebase implements RestModifyView<RevisionResource, RebaseInput>,
UiAction<RevisionResource> { UiAction<RevisionResource> {
private static final Logger log = LoggerFactory.getLogger(Rebase.class); private static final Logger log = LoggerFactory.getLogger(Rebase.class);
private static final EnumSet<ListChangesOption> OPTIONS = EnumSet.of(
ListChangesOption.CURRENT_REVISION,
ListChangesOption.CURRENT_COMMIT);
private final GitRepositoryManager repoManager; private final GitRepositoryManager repoManager;
private final Provider<RebaseChange> rebaseChange; private final Provider<RebaseChange> rebaseChange;
private final ChangeJson json; private final ChangeJson.Factory json;
private final Provider<ReviewDb> dbProvider; private final Provider<ReviewDb> dbProvider;
@Inject @Inject
public Rebase(GitRepositoryManager repoManager, public Rebase(GitRepositoryManager repoManager,
Provider<RebaseChange> rebaseChange, Provider<RebaseChange> rebaseChange,
ChangeJson json, ChangeJson.Factory json,
Provider<ReviewDb> dbProvider) { Provider<ReviewDb> dbProvider) {
this.repoManager = repoManager; this.repoManager = repoManager;
this.rebaseChange = rebaseChange; this.rebaseChange = rebaseChange;
this.json = json this.json = json;
.addOption(ListChangesOption.CURRENT_REVISION)
.addOption(ListChangesOption.CURRENT_COMMIT);
this.dbProvider = dbProvider; this.dbProvider = dbProvider;
} }
@@ -97,7 +98,7 @@ public class Rebase implements RestModifyView<RevisionResource, RebaseInput>,
throw new ResourceNotFoundException(change.getId().toString()); throw new ResourceNotFoundException(change.getId().toString());
} }
return json.format(change.getId()); return json.create(OPTIONS).format(change.getId());
} }
private String findBaseRev(RevWalk rw, RevisionResource rsrc, private String findBaseRev(RevWalk rw, RevisionResource rsrc,

View File

@@ -53,7 +53,7 @@ public class Restore implements RestModifyView<ChangeResource, RestoreInput>,
private final ChangeHooks hooks; private final ChangeHooks hooks;
private final RestoredSender.Factory restoredSenderFactory; private final RestoredSender.Factory restoredSenderFactory;
private final Provider<ReviewDb> dbProvider; private final Provider<ReviewDb> dbProvider;
private final ChangeJson json; private final ChangeJson.Factory json;
private final ChangeIndexer indexer; private final ChangeIndexer indexer;
private final ChangeMessagesUtil cmUtil; private final ChangeMessagesUtil cmUtil;
private final ChangeUpdate.Factory updateFactory; private final ChangeUpdate.Factory updateFactory;
@@ -62,7 +62,7 @@ public class Restore implements RestModifyView<ChangeResource, RestoreInput>,
Restore(ChangeHooks hooks, Restore(ChangeHooks hooks,
RestoredSender.Factory restoredSenderFactory, RestoredSender.Factory restoredSenderFactory,
Provider<ReviewDb> dbProvider, Provider<ReviewDb> dbProvider,
ChangeJson json, ChangeJson.Factory json,
ChangeIndexer indexer, ChangeIndexer indexer,
ChangeMessagesUtil cmUtil, ChangeMessagesUtil cmUtil,
ChangeUpdate.Factory updateFactory) { ChangeUpdate.Factory updateFactory) {
@@ -136,8 +136,7 @@ public class Restore implements RestModifyView<ChangeResource, RestoreInput>,
db.patchSets().get(change.currentPatchSetId()), db.patchSets().get(change.currentPatchSetId()),
Strings.emptyToNull(input.message), Strings.emptyToNull(input.message),
dbProvider.get()); dbProvider.get());
ChangeInfo result = json.format(change); return json.create(ChangeJson.NO_OPTIONS).format(change);
return result;
} }
@Override @Override

View File

@@ -44,12 +44,12 @@ import java.io.IOException;
@Singleton @Singleton
public class Revert implements RestModifyView<ChangeResource, RevertInput>, public class Revert implements RestModifyView<ChangeResource, RevertInput>,
UiAction<ChangeResource> { UiAction<ChangeResource> {
private final ChangeJson json; private final ChangeJson.Factory json;
private final ChangeUtil changeUtil; private final ChangeUtil changeUtil;
private final PersonIdent myIdent; private final PersonIdent myIdent;
@Inject @Inject
Revert(ChangeJson json, Revert(ChangeJson.Factory json,
ChangeUtil changeUtil, ChangeUtil changeUtil,
@GerritPersonIdent PersonIdent myIdent) { @GerritPersonIdent PersonIdent myIdent) {
this.json = json; this.json = json;
@@ -69,18 +69,19 @@ public class Revert implements RestModifyView<ChangeResource, RevertInput>,
throw new ResourceConflictException("change is " + status(change)); throw new ResourceConflictException("change is " + status(change));
} }
Change.Id revertedChangeId;
try { try {
Change.Id revertedChangeId = revertedChangeId = changeUtil.revert(control,
changeUtil.revert(control, change.currentPatchSetId(), change.currentPatchSetId(),
Strings.emptyToNull(input.message), Strings.emptyToNull(input.message),
new PersonIdent(myIdent, TimeUtil.nowTs()), new NoSshInfo()); new PersonIdent(myIdent, TimeUtil.nowTs()),
new NoSshInfo());
return json.format(revertedChangeId);
} catch (InvalidChangeOperationException e) { } catch (InvalidChangeOperationException e) {
throw new BadRequestException(e.getMessage()); throw new BadRequestException(e.getMessage());
} catch (NoSuchChangeException e) { } catch (NoSuchChangeException e) {
throw new ResourceNotFoundException(e.getMessage()); throw new ResourceNotFoundException(e.getMessage());
} }
return json.create(ChangeJson.NO_OPTIONS).format(revertedChangeId);
} }
@Override @Override

View File

@@ -472,12 +472,12 @@ public class Submit implements RestModifyView<RevisionResource, SubmitInput>,
RestModifyView<ChangeResource, SubmitInput> { RestModifyView<ChangeResource, SubmitInput> {
private final Provider<ReviewDb> dbProvider; private final Provider<ReviewDb> dbProvider;
private final Submit submit; private final Submit submit;
private final ChangeJson json; private final ChangeJson.Factory json;
@Inject @Inject
CurrentRevision(Provider<ReviewDb> dbProvider, CurrentRevision(Provider<ReviewDb> dbProvider,
Submit submit, Submit submit,
ChangeJson json) { ChangeJson.Factory json) {
this.dbProvider = dbProvider; this.dbProvider = dbProvider;
this.submit = submit; this.submit = submit;
this.json = json; this.json = json;
@@ -495,8 +495,9 @@ public class Submit implements RestModifyView<RevisionResource, SubmitInput>,
} else if (!rsrc.getControl().isPatchVisible(ps, dbProvider.get())) { } else if (!rsrc.getControl().isPatchVisible(ps, dbProvider.get())) {
throw new AuthException("current revision not accessible"); throw new AuthException("current revision not accessible");
} }
Output out = submit.apply(new RevisionResource(rsrc, ps), input); Output out = submit.apply(new RevisionResource(rsrc, ps), input);
return json.format(out.change); return json.create(ChangeJson.NO_OPTIONS).format(out.change);
} }
} }
} }

View File

@@ -40,13 +40,12 @@ public class SubmittedTogether implements RestReadView<ChangeResource> {
private static final Logger log = LoggerFactory.getLogger( private static final Logger log = LoggerFactory.getLogger(
SubmittedTogether.class); SubmittedTogether.class);
private final ChangeJson json; private final ChangeJson.Factory json;
private final Provider<ReviewDb> dbProvider; private final Provider<ReviewDb> dbProvider;
private final MergeSuperSet mergeSuperSet; private final MergeSuperSet mergeSuperSet;
@Inject @Inject
SubmittedTogether(ChangeJson json, SubmittedTogether(ChangeJson.Factory json,
Provider<ReviewDb> dbProvider, Provider<ReviewDb> dbProvider,
MergeSuperSet mergeSuperSet) { MergeSuperSet mergeSuperSet) {
this.json = json; this.json = json;
@@ -61,12 +60,12 @@ public class SubmittedTogether implements RestReadView<ChangeResource> {
try { try {
ChangeSet cs = mergeSuperSet.completeChangeSet(dbProvider.get(), ChangeSet cs = mergeSuperSet.completeChangeSet(dbProvider.get(),
ChangeSet.create(resource.getChange())); ChangeSet.create(resource.getChange()));
json.addOptions(EnumSet.of( return json.create(EnumSet.of(
ListChangesOption.CURRENT_REVISION, ListChangesOption.CURRENT_REVISION,
ListChangesOption.CURRENT_COMMIT, ListChangesOption.CURRENT_COMMIT,
ListChangesOption.DETAILED_LABELS, ListChangesOption.DETAILED_LABELS,
ListChangesOption.LABELS)); ListChangesOption.LABELS))
return json.format(cs.ids()); .format(cs.ids());
} catch (OrmException | IOException e) { } catch (OrmException | IOException e) {
log.error("Error on getting a ChangeSet", e); log.error("Error on getting a ChangeSet", e);
throw e; throw e;

View File

@@ -69,6 +69,7 @@ import com.google.gerrit.server.auth.AuthBackend;
import com.google.gerrit.server.auth.UniversalAuthBackend; import com.google.gerrit.server.auth.UniversalAuthBackend;
import com.google.gerrit.server.avatar.AvatarProvider; import com.google.gerrit.server.avatar.AvatarProvider;
import com.google.gerrit.server.cache.CacheRemovalListener; import com.google.gerrit.server.cache.CacheRemovalListener;
import com.google.gerrit.server.change.ChangeJson;
import com.google.gerrit.server.change.ChangeKindCacheImpl; import com.google.gerrit.server.change.ChangeKindCacheImpl;
import com.google.gerrit.server.change.MergeabilityCacheImpl; import com.google.gerrit.server.change.MergeabilityCacheImpl;
import com.google.gerrit.server.events.EventFactory; import com.google.gerrit.server.events.EventFactory;
@@ -186,6 +187,7 @@ public class GerritGlobalModule extends FactoryModule {
factory(AddReviewerSender.Factory.class); factory(AddReviewerSender.Factory.class);
factory(CapabilityControl.Factory.class); factory(CapabilityControl.Factory.class);
factory(ChangeData.Factory.class); factory(ChangeData.Factory.class);
factory(ChangeJson.Factory.class);
factory(CreateChangeSender.Factory.class); factory(CreateChangeSender.Factory.class);
factory(GroupDetailFactory.Factory.class); factory(GroupDetailFactory.Factory.class);
factory(GroupInfoCacheFactory.Factory.class); factory(GroupInfoCacheFactory.Factory.class);

View File

@@ -38,7 +38,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
public class QueryChanges implements RestReadView<TopLevelResource> { public class QueryChanges implements RestReadView<TopLevelResource> {
private final ChangeJson json; private final ChangeJson.Factory json;
private final ChangeQueryBuilder qb; private final ChangeQueryBuilder qb;
private final QueryProcessor imp; private final QueryProcessor imp;
private final Provider<CurrentUser> user; private final Provider<CurrentUser> user;
@@ -68,7 +68,7 @@ public class QueryChanges implements RestReadView<TopLevelResource> {
} }
@Inject @Inject
QueryChanges(ChangeJson json, QueryChanges(ChangeJson.Factory json,
ChangeQueryBuilder qb, ChangeQueryBuilder qb,
QueryProcessor qp, QueryProcessor qp,
Provider<CurrentUser> user) { Provider<CurrentUser> user) {
@@ -141,7 +141,7 @@ public class QueryChanges implements RestReadView<TopLevelResource> {
QueryParseException { QueryParseException {
int cnt = queries.size(); int cnt = queries.size();
List<QueryResult> results = imp.queryChanges(qb.parse(queries)); List<QueryResult> results = imp.queryChanges(qb.parse(queries));
List<List<ChangeInfo>> res = json.addOptions(options) List<List<ChangeInfo>> res = json.create(options)
.formatQueryResults(results); .formatQueryResults(results);
for (int n = 0; n < cnt; n++) { for (int n = 0; n < cnt; n++) {
List<ChangeInfo> info = res.get(n); List<ChangeInfo> info = res.get(n);