1   /*
2    * Copyright 2024 LINE Corporation
3    *
4    * LINE Corporation licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   https://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  package com.linecorp.centraldogma.server.metadata;
17  
18  import static java.util.Objects.requireNonNull;
19  
20  import java.util.Map;
21  import java.util.Map.Entry;
22  
23  import javax.annotation.Nullable;
24  
25  import com.fasterxml.jackson.annotation.JsonCreator;
26  import com.fasterxml.jackson.annotation.JsonProperty;
27  import com.google.common.base.MoreObjects;
28  import com.google.common.base.Objects;
29  import com.google.common.collect.ImmutableMap;
30  
31  import com.linecorp.centraldogma.common.RepositoryRole;
32  import com.linecorp.centraldogma.server.storage.repository.HasWeight;
33  
34  /**
35   * Role metadata for a repository.
36   */
37  public final class Roles implements HasWeight {
38  
39      static final Roles EMPTY = new Roles(ProjectRoles.of(null, null),
40                                           ImmutableMap.of(), null, ImmutableMap.of());
41  
42      private final ProjectRoles projectRoles;
43  
44      private final Map<String, RepositoryRole> users;
45  
46      private final Map<String, RepositoryRole> appIds;
47  
48      /**
49       * Creates a new instance.
50       */
51      @JsonCreator
52      public Roles(@JsonProperty("projects") ProjectRoles projectRoles,
53                   @JsonProperty("users") Map<String, RepositoryRole> users,
54                   @JsonProperty("tokens") @Nullable Map<String, RepositoryRole> tokens,
55                   @JsonProperty("appIds") @Nullable Map<String, RepositoryRole> appIds) {
56          this.projectRoles = requireNonNull(projectRoles, "projectRoles");
57          this.users = requireNonNull(users, "users");
58          if (tokens == null && appIds == null) {
59              throw new IllegalArgumentException("Both tokens and appIds are null");
60          }
61  
62          if (appIds != null) {
63              this.appIds = ImmutableMap.copyOf(appIds);
64          } else {
65              this.appIds = ImmutableMap.copyOf(tokens);
66          }
67      }
68  
69      /**
70       * Returns the {@link ProjectRoles} of the repository.
71       */
72      @JsonProperty("projects")
73      public ProjectRoles projectRoles() {
74          return projectRoles;
75      }
76  
77      /**
78       * Returns the {@link RepositoryRole}s of users.
79       */
80      @JsonProperty("users")
81      public Map<String, RepositoryRole> users() {
82          return users;
83      }
84  
85      /**
86       * Returns the {@link RepositoryRole}s of app IDs.
87       */
88      @JsonProperty("appIds")
89      public Map<String, RepositoryRole> appIds() {
90          return appIds;
91      }
92  
93      @Override
94      public int weight() {
95          int weight = 0;
96          final RepositoryRole member = projectRoles.member();
97          if (member != null) {
98              weight += member.name().length();
99          }
100         for (Entry<String, RepositoryRole> entry : users.entrySet()) {
101             weight += entry.getKey().length();
102             weight += entry.getValue().name().length();
103         }
104         for (Entry<String, RepositoryRole> entry : appIds.entrySet()) {
105             weight += entry.getKey().length();
106             weight += entry.getValue().name().length();
107         }
108         return weight;
109     }
110 
111     @Override
112     public boolean equals(Object o) {
113         if (this == o) {
114             return true;
115         }
116         if (!(o instanceof Roles)) {
117             return false;
118         }
119         final Roles other = (Roles) o;
120         return projectRoles.equals(other.projectRoles) &&
121                users.equals(other.users) &&
122                appIds.equals(other.appIds);
123     }
124 
125     @Override
126     public int hashCode() {
127         return Objects.hashCode(projectRoles, users, appIds);
128     }
129 
130     @Override
131     public String toString() {
132         return MoreObjects.toStringHelper(this)
133                           .add("projectRoles", projectRoles)
134                           .add("users", users)
135                           .add("appIds", appIds)
136                           .toString();
137     }
138 }