summaryrefslogtreecommitdiffstats
path: root/java/com/google/gerrit/server/change/RevisionResource.java
blob: 30fa593b097d861f05b96af17a96ca0336891c09 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
// Copyright (C) 2012 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.gerrit.server.change;

import com.google.common.hash.Hasher;
import com.google.common.hash.Hashing;
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.PatchSet;
import com.google.gerrit.entities.Project;
import com.google.gerrit.extensions.restapi.RestResource;
import com.google.gerrit.extensions.restapi.RestResource.HasETag;
import com.google.gerrit.extensions.restapi.RestView;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.edit.ChangeEdit;
import com.google.gerrit.server.logging.Metadata;
import com.google.gerrit.server.logging.TraceContext;
import com.google.gerrit.server.logging.TraceContext.TraceTimer;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.inject.TypeLiteral;
import java.util.Optional;

public class RevisionResource implements RestResource, HasETag {
  public static final TypeLiteral<RestView<RevisionResource>> REVISION_KIND =
      new TypeLiteral<RestView<RevisionResource>>() {};

  public static RevisionResource createNonCacheable(ChangeResource change, PatchSet ps) {
    return new RevisionResource(change, ps, Optional.empty(), false);
  }

  private final ChangeResource change;
  private final PatchSet ps;
  private final Optional<ChangeEdit> edit;
  private final boolean cacheable;

  public RevisionResource(ChangeResource change, PatchSet ps) {
    this(change, ps, Optional.empty());
  }

  public RevisionResource(ChangeResource change, PatchSet ps, Optional<ChangeEdit> edit) {
    this(change, ps, edit, true);
  }

  private RevisionResource(
      ChangeResource change, PatchSet ps, Optional<ChangeEdit> edit, boolean cacheable) {
    this.change = change;
    this.ps = ps;
    this.edit = edit;
    this.cacheable = cacheable;
  }

  public boolean isCacheable() {
    return cacheable;
  }

  public PermissionBackend.ForChange permissions() {
    return change.permissions();
  }

  public ChangeResource getChangeResource() {
    return change;
  }

  public Change getChange() {
    return getChangeResource().getChange();
  }

  public Project.NameKey getProject() {
    return getChange().getProject();
  }

  public ChangeNotes getNotes() {
    return getChangeResource().getNotes();
  }

  public PatchSet getPatchSet() {
    return ps;
  }

  @Override
  public String getETag() {
    try (TraceTimer ignored =
        TraceContext.newTimer(
            "Compute revision ETag",
            Metadata.builder()
                .changeId(change.getId().get())
                .patchSetId(ps.number())
                .projectName(change.getProject().get())
                .build())) {
      Hasher h = Hashing.murmur3_128().newHasher();
      prepareETag(h, getUser());
      return h.hash().toString();
    }
  }

  public void prepareETag(Hasher h, CurrentUser user) {
    // Conservative estimate: refresh the revision if its parent change has changed, so we don't
    // have to check whether a given modification affected this revision specifically.
    change.prepareETag(h, user);
  }

  public Account.Id getAccountId() {
    return getUser().getAccountId();
  }

  public CurrentUser getUser() {
    return getChangeResource().getUser();
  }

  public Optional<ChangeEdit> getEdit() {
    return edit;
  }

  @Override
  public String toString() {
    String s = ps.id().toString();
    if (edit.isPresent()) {
      s = "edit:" + s;
    }
    return s;
  }

  public boolean isCurrent() {
    return ps.id().equals(getChange().currentPatchSetId());
  }
}