summaryrefslogtreecommitdiffstats
path: root/java/com/google/gerrit/server/account/externalids/AllExternalIds.java
blob: 8b23f6c396bac2fdb475837fc5c8f5d981b927f0 (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
// Copyright (C) 2018 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.account.externalids;

import static com.google.common.collect.ImmutableSetMultimap.toImmutableSetMultimap;
import static java.util.stream.Collectors.toList;

import com.google.auto.value.AutoValue;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.collect.SetMultimap;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.server.cache.proto.Cache.AllExternalIdsProto;
import com.google.gerrit.server.cache.proto.Cache.AllExternalIdsProto.ExternalIdProto;
import com.google.gerrit.server.cache.serialize.CacheSerializer;
import com.google.gerrit.server.cache.serialize.ProtoCacheSerializers;
import com.google.gerrit.server.cache.serialize.ProtoCacheSerializers.ObjectIdConverter;
import java.util.Collection;

/** Cache value containing all external IDs. */
@AutoValue
public abstract class AllExternalIds {
  static AllExternalIds create(SetMultimap<Account.Id, ExternalId> byAccount) {
    return new AutoValue_AllExternalIds(
        ImmutableSetMultimap.copyOf(byAccount), byEmailCopy(byAccount.values()));
  }

  static AllExternalIds create(Collection<ExternalId> externalIds) {
    return new AutoValue_AllExternalIds(
        externalIds.stream().collect(toImmutableSetMultimap(e -> e.accountId(), e -> e)),
        byEmailCopy(externalIds));
  }

  private static ImmutableSetMultimap<String, ExternalId> byEmailCopy(
      Collection<ExternalId> externalIds) {
    return externalIds.stream()
        .filter(e -> !Strings.isNullOrEmpty(e.email()))
        .collect(toImmutableSetMultimap(e -> e.email(), e -> e));
  }

  public abstract ImmutableSetMultimap<Account.Id, ExternalId> byAccount();

  public abstract ImmutableSetMultimap<String, ExternalId> byEmail();

  enum Serializer implements CacheSerializer<AllExternalIds> {
    INSTANCE;

    @Override
    public byte[] serialize(AllExternalIds object) {
      ObjectIdConverter idConverter = ObjectIdConverter.create();
      AllExternalIdsProto.Builder allBuilder = AllExternalIdsProto.newBuilder();
      object.byAccount().values().stream()
          .map(extId -> toProto(idConverter, extId))
          .forEach(allBuilder::addExternalId);
      return ProtoCacheSerializers.toByteArray(allBuilder.build());
    }

    private static ExternalIdProto toProto(ObjectIdConverter idConverter, ExternalId externalId) {
      ExternalIdProto.Builder b =
          ExternalIdProto.newBuilder()
              .setKey(externalId.key().get())
              .setAccountId(externalId.accountId().get());
      if (externalId.email() != null) {
        b.setEmail(externalId.email());
      }
      if (externalId.password() != null) {
        b.setPassword(externalId.password());
      }
      if (externalId.blobId() != null) {
        b.setBlobId(idConverter.toByteString(externalId.blobId()));
      }
      return b.build();
    }

    @Override
    public AllExternalIds deserialize(byte[] in) {
      ObjectIdConverter idConverter = ObjectIdConverter.create();
      return create(
          ProtoCacheSerializers.parseUnchecked(AllExternalIdsProto.parser(), in).getExternalIdList()
              .stream()
              .map(proto -> toExternalId(idConverter, proto))
              .collect(toList()));
    }

    private static ExternalId toExternalId(ObjectIdConverter idConverter, ExternalIdProto proto) {
      return ExternalId.create(
          ExternalId.Key.parse(proto.getKey()),
          new Account.Id(proto.getAccountId()),
          // ExternalId treats null and empty strings the same, so no need to distinguish here.
          proto.getEmail(),
          proto.getPassword(),
          !proto.getBlobId().isEmpty() ? idConverter.fromByteString(proto.getBlobId()) : null);
    }
  }
}