All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.gerrit.server.account.AccountDelta Maven / Gradle / Ivy

There is a newer version: 3.11.0-rc3
Show newest version
// Copyright (C) 2017 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 Licens

package com.google.gerrit.server.account;

import com.google.auto.value.AutoValue;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.NotifyConfig.NotifyType;
import com.google.gerrit.extensions.client.DiffPreferencesInfo;
import com.google.gerrit.extensions.client.EditPreferencesInfo;
import com.google.gerrit.extensions.client.GeneralPreferencesInfo;
import com.google.gerrit.server.account.ProjectWatches.ProjectWatchKey;
import com.google.gerrit.server.account.externalids.DuplicateExternalIdKeyException;
import com.google.gerrit.server.account.externalids.ExternalId;
import java.util.Collection;
import java.util.Map;
import java.util.Optional;
import java.util.Set;

/**
 * Data holder for updates to be applied to an account.
 *
 * 

Instances of this type are passed to {@link AccountsUpdate}, which modifies the account * accordingly. * *

Updates can be applied to account properties (name, email etc.), external IDs, preferences * (general, diff and edit preferences) and project watches. The account ID and the registration * date cannot be updated. * *

For the account properties there are getters in this class and setters in the {@link Builder} * that correspond to the fields in {@link Account}. */ @AutoValue public abstract class AccountDelta { public static Builder builder() { return new Builder.WrapperThatConvertsNullStringArgsToEmptyStrings( new AutoValue_AccountDelta.Builder()); } /** * Returns the new value for the full name. * * @return the new value for the full name, {@code Optional#empty()} if the full name is not being * updated, {@code Optional#of("")} if the full name is unset, the wrapped value is never * {@code null} */ public abstract Optional getFullName(); /** * Returns the new value for the display name. * * @return the new value for the display name, {@code Optional#empty()} if the display name is not * being updated, {@code Optional#of("")} if the display name is unset, the wrapped value is * never {@code null} */ public abstract Optional getDisplayName(); /** * Returns the new value for the preferred email. * * @return the new value for the preferred email, {@code Optional#empty()} if the preferred email * is not being updated, {@code Optional#of("")} if the preferred email is unset, the wrapped * value is never {@code null} */ public abstract Optional getPreferredEmail(); /** * Returns the new value for the active flag. * * @return the new value for the active flag, {@code Optional#empty()} if the active flag is not * being updated, the wrapped value is never {@code null} */ public abstract Optional getActive(); /** * Returns the new value for the status. * * @return the new value for the status, {@code Optional#empty()} if the status is not being * updated, {@code Optional#of("")} if the status is unset, the wrapped value is never {@code * null} */ public abstract Optional getStatus(); /** * Returns external IDs that should be newly created for the account. * * @return external IDs that should be newly created for the account */ public abstract ImmutableSet getCreatedExternalIds(); /** * Returns external IDs that should be updated for the account. * * @return external IDs that should be updated for the account */ public abstract ImmutableSet getUpdatedExternalIds(); /** * Returns external IDs that should be deleted for the account. * * @return external IDs that should be deleted for the account */ public abstract ImmutableSet getDeletedExternalIds(); /** * Returns external IDs that should be updated for the account. * * @return external IDs that should be updated for the account */ public abstract ImmutableMap> getUpdatedProjectWatches(); /** * Returns project watches that should be deleted for the account. * * @return project watches that should be deleted for the account */ public abstract ImmutableSet getDeletedProjectWatches(); /** * Returns the new value for the general preferences. * *

Only preferences that are non-null in the returned GeneralPreferencesInfo should be updated. * * @return the new value for the general preferences, {@code Optional#empty()} if the general * preferences are not being updated, the wrapped value is never {@code null} */ public abstract Optional getGeneralPreferences(); /** * Returns the new value for the diff preferences. * *

Only preferences that are non-null in the returned DiffPreferencesInfo should be updated. * * @return the new value for the diff preferences, {@code Optional#empty()} if the diff * preferences are not being updated, the wrapped value is never {@code null} */ public abstract Optional getDiffPreferences(); /** * Returns the new value for the edit preferences. * *

Only preferences that are non-null in the returned DiffPreferencesInfo should be updated. * * @return the new value for the edit preferences, {@code Optional#empty()} if the edit * preferences are not being updated, the wrapped value is never {@code null} */ public abstract Optional getEditPreferences(); /** * Returns whether the delta for this account is deleting the account. * *

If set to true, deletion takes precedence on any other change in this delta. * * @return whether the account should be deleted. */ public abstract Optional getShouldDeleteAccount(); public boolean hasExternalIdUpdates() { return !this.getCreatedExternalIds().isEmpty() || !this.getDeletedExternalIds().isEmpty() || !this.getUpdatedExternalIds().isEmpty(); } /** * Class to build an {@link AccountDelta}. * *

Account data is only updated if the corresponding setter is invoked. If a setter is not * invoked the corresponding data stays unchanged. To unset string values the setter can be * invoked with either {@code null} or an empty string ({@code null} is converted to an empty * string by using the {@link WrapperThatConvertsNullStringArgsToEmptyStrings} wrapper, see {@link * AccountDelta#builder()}). */ @AutoValue.Builder public abstract static class Builder { /** * Sets a new full name for the account. * * @param fullName the new full name, if {@code null} or empty string the full name is unset */ @CanIgnoreReturnValue public abstract Builder setFullName(@Nullable String fullName); /** * Sets a new display name for the account. * * @param displayName the new display name, if {@code null} or empty string the display name is * unset */ @CanIgnoreReturnValue public abstract Builder setDisplayName(@Nullable String displayName); /** * Sets a new preferred email for the account. * * @param preferredEmail the new preferred email, if {@code null} or empty string the preferred * email is unset */ @CanIgnoreReturnValue public abstract Builder setPreferredEmail(@Nullable String preferredEmail); /** * Sets the active flag for the account. * * @param active {@code true} if the account should be set to active, {@code false} if the * account should be set to inactive */ @CanIgnoreReturnValue public abstract Builder setActive(boolean active); /** * Sets a new status for the account. * * @param status the new status, if {@code null} or empty string the status is unset */ @CanIgnoreReturnValue public abstract Builder setStatus(@Nullable String status); /** * Returns a builder for the set of created external IDs. * * @return builder for the set of created external IDs. */ abstract ImmutableSet.Builder createdExternalIdsBuilder(); /** * Adds a new external ID for the account. * *

The account ID of the external ID must match the account ID of the account that is * updated. * *

If an external ID with the same ID already exists the account update will fail with {@link * DuplicateExternalIdKeyException}. * * @param extId external ID that should be added * @return the builder */ @CanIgnoreReturnValue public Builder addExternalId(ExternalId extId) { return addExternalIds(ImmutableSet.of(extId)); } /** * Adds new external IDs for the account. * *

The account IDs of the external IDs must match the account ID of the account that is * updated. * *

If any of the external ID keys already exists, the insert fails with {@link * DuplicateExternalIdKeyException}. * * @param extIds external IDs that should be added * @return the builder */ @CanIgnoreReturnValue public Builder addExternalIds(Collection extIds) { createdExternalIdsBuilder().addAll(extIds); return this; } /** * Returns a builder for the set of updated external IDs. * * @return builder for the set of updated external IDs. */ abstract ImmutableSet.Builder updatedExternalIdsBuilder(); /** * Updates an external ID for the account. * *

The account ID of the external ID must match the account ID of the account that is * updated. * *

If no external ID with the ID exists the external ID is created. * * @param extId external ID that should be updated * @return the builder */ @CanIgnoreReturnValue public Builder updateExternalId(ExternalId extId) { return updateExternalIds(ImmutableSet.of(extId)); } /** * Updates external IDs for the account. * *

The account IDs of the external IDs must match the account ID of the account that is * updated. * *

If any of the external IDs already exists, it is overwritten. New external IDs are * inserted. * * @param extIds external IDs that should be updated * @return the builder */ @CanIgnoreReturnValue public Builder updateExternalIds(Collection extIds) { updatedExternalIdsBuilder().addAll(extIds); return this; } /** * Returns a builder for the set of deleted external IDs. * * @return builder for the set of deleted external IDs. */ abstract ImmutableSet.Builder deletedExternalIdsBuilder(); /** * Deletes an external ID for the account. * *

The account ID of the external ID must match the account ID of the account that is * updated. * *

If no external ID with the ID exists this is a no-op. * * @param extId external ID that should be deleted * @return the builder */ @CanIgnoreReturnValue public Builder deleteExternalId(ExternalId extId) { return deleteExternalIds(ImmutableSet.of(extId)); } /** * Deletes external IDs for the account. * *

The account IDs of the external IDs must match the account ID of the account that is * updated. * *

For non-existing external IDs this is a no-op. * * @param extIds external IDs that should be deleted * @return the builder */ @CanIgnoreReturnValue public Builder deleteExternalIds(Collection extIds) { deletedExternalIdsBuilder().addAll(extIds); return this; } /** * Replaces an external ID. * * @param extIdToDelete external ID that should be deleted * @param extIdToAdd external ID that should be added * @return the builder */ @CanIgnoreReturnValue public Builder replaceExternalId(ExternalId extIdToDelete, ExternalId extIdToAdd) { return replaceExternalIds(ImmutableSet.of(extIdToDelete), ImmutableSet.of(extIdToAdd)); } /** * Replaces an external IDs. * * @param extIdsToDelete external IDs that should be deleted * @param extIdsToAdd external IDs that should be added * @return the builder */ @CanIgnoreReturnValue public Builder replaceExternalIds( Collection extIdsToDelete, Collection extIdsToAdd) { return deleteExternalIds(extIdsToDelete).addExternalIds(extIdsToAdd); } /** * Returns a builder for the map of updated project watches. * * @return builder for the map of updated project watches. */ abstract ImmutableMap.Builder> updatedProjectWatchesBuilder(); /** * Updates a project watch for the account. * *

If no project watch with the key exists the project watch is created. * * @param projectWatchKey key of the project watch that should be updated * @param notifyTypes the notify types that should be set for the project watch * @return the builder */ @CanIgnoreReturnValue public Builder updateProjectWatch( ProjectWatchKey projectWatchKey, Set notifyTypes) { return updateProjectWatches(ImmutableMap.of(projectWatchKey, notifyTypes)); } /** * Updates project watches for the account. * *

If any of the project watches already exists, it is overwritten. New project watches are * inserted. * * @param projectWatches project watches that should be updated * @return the builder */ @CanIgnoreReturnValue public Builder updateProjectWatches(Map> projectWatches) { updatedProjectWatchesBuilder().putAll(projectWatches); return this; } /** * Returns a builder for the set of deleted project watches. * * @return builder for the set of deleted project watches. */ abstract ImmutableSet.Builder deletedProjectWatchesBuilder(); /** * Deletes a project watch for the account. * *

If no project watch with the ID exists this is a no-op. * * @param projectWatch project watch that should be deleted * @return the builder */ @CanIgnoreReturnValue public Builder deleteProjectWatch(ProjectWatchKey projectWatch) { return deleteProjectWatches(ImmutableSet.of(projectWatch)); } /** * Deletes project watches for the account. * *

For non-existing project watches this is a no-op. * * @param projectWatches project watches that should be deleted * @return the builder */ @CanIgnoreReturnValue public Builder deleteProjectWatches(Collection projectWatches) { deletedProjectWatchesBuilder().addAll(projectWatches); return this; } /** * Sets the general preferences for the account. * *

Updates any preference that is non-null in the provided GeneralPreferencesInfo. * * @param generalPreferences the general preferences that should be set * @return the builder */ @CanIgnoreReturnValue public abstract Builder setGeneralPreferences(GeneralPreferencesInfo generalPreferences); /** * Sets the diff preferences for the account. * *

Updates any preference that is non-null in the provided DiffPreferencesInfo. * * @param diffPreferences the diff preferences that should be set * @return the builder */ @CanIgnoreReturnValue public abstract Builder setDiffPreferences(DiffPreferencesInfo diffPreferences); /** * Sets the edit preferences for the account. * *

Updates any preference that is non-null in the provided EditPreferencesInfo. * * @param editPreferences the edit preferences that should be set * @return the builder */ @CanIgnoreReturnValue public abstract Builder setEditPreferences(EditPreferencesInfo editPreferences); @CanIgnoreReturnValue public abstract Builder setShouldDeleteAccount(boolean shouldDelete); /** * Builds an AccountDelta that deletes all data. * * @param extIdsToDelete external IDs that should be deleted * @return the builder */ @CanIgnoreReturnValue public Builder deleteAccount(Collection extIdsToDelete) { deleteExternalIds(extIdsToDelete); setShouldDeleteAccount(true); return this; } /** Builds the instance. */ public abstract AccountDelta build(); /** * Wrapper for {@link Builder} that converts {@code null} string arguments to empty strings for * all setter methods. This allows us to treat setter invocations with a {@code null} string * argument as signal to unset the corresponding field. E.g. for a builder method {@code * setX(String)} the following semantics apply: * *

    *
  • Method is not invoked: X stays unchanged, X is stored as {@code Optional.empty()}. *
  • Argument is a non-empty string Y: X is updated to the Y, X is stored as {@code * Optional.of(Y)}. *
  • Argument is an empty string: X is unset, X is stored as {@code Optional.of("")} *
  • Argument is {@code null}: X is unset, X is stored as {@code Optional.of("")} (since the * wrapper converts {@code null} to an empty string) *
* * Without the wrapper calling {@code setX(null)} would fail with a {@link * NullPointerException}. Hence all callers would need to take care to call {@link * Strings#nullToEmpty(String)} for all string arguments and likely it would be forgotten in * some places. * *

This means the stored values are interpreted like this: * *

    *
  • {@code Optional.empty()}: property stays unchanged *
  • {@code Optional.of()}: property is updated *
  • {@code Optional.of("")}: property is unset *
* * This wrapper forwards all method invocations to the wrapped {@link Builder} instance that was * created by AutoValue. For methods that return the AutoValue {@link Builder} instance the * return value is replaced with the wrapper instance so that all chained calls go through the * wrapper. */ private static class WrapperThatConvertsNullStringArgsToEmptyStrings extends Builder { private final Builder delegate; private WrapperThatConvertsNullStringArgsToEmptyStrings(Builder delegate) { this.delegate = delegate; } @Override public Builder setFullName(String fullName) { delegate.setFullName(Strings.nullToEmpty(fullName)); return this; } @Override public Builder setDisplayName(String displayName) { delegate.setDisplayName(Strings.nullToEmpty(displayName)); return this; } @Override public Builder setPreferredEmail(String preferredEmail) { delegate.setPreferredEmail(Strings.nullToEmpty(preferredEmail)); return this; } @Override public Builder setActive(boolean active) { delegate.setActive(active); return this; } @Override public Builder setStatus(String status) { delegate.setStatus(Strings.nullToEmpty(status)); return this; } @Override public AccountDelta build() { return delegate.build(); } @Override ImmutableSet.Builder createdExternalIdsBuilder() { return delegate.createdExternalIdsBuilder(); } @Override public Builder addExternalIds(Collection extIds) { delegate.addExternalIds(extIds); return this; } @Override ImmutableSet.Builder updatedExternalIdsBuilder() { return delegate.updatedExternalIdsBuilder(); } @Override public Builder updateExternalIds(Collection extIds) { delegate.updateExternalIds(extIds); return this; } @Override ImmutableSet.Builder deletedExternalIdsBuilder() { return delegate.deletedExternalIdsBuilder(); } @Override public Builder deleteExternalIds(Collection extIds) { delegate.deleteExternalIds(extIds); return this; } @Override ImmutableMap.Builder> updatedProjectWatchesBuilder() { return delegate.updatedProjectWatchesBuilder(); } @Override public Builder updateProjectWatches(Map> projectWatches) { delegate.updateProjectWatches(projectWatches); return this; } @Override ImmutableSet.Builder deletedProjectWatchesBuilder() { return delegate.deletedProjectWatchesBuilder(); } @Override public Builder deleteProjectWatches(Collection projectWatches) { delegate.deleteProjectWatches(projectWatches); return this; } @Override public Builder setGeneralPreferences(GeneralPreferencesInfo generalPreferences) { delegate.setGeneralPreferences(generalPreferences); return this; } @Override public Builder setDiffPreferences(DiffPreferencesInfo diffPreferences) { delegate.setDiffPreferences(diffPreferences); return this; } @Override public Builder setEditPreferences(EditPreferencesInfo editPreferences) { delegate.setEditPreferences(editPreferences); return this; } @Override public Builder setShouldDeleteAccount(boolean shouldDelete) { delegate.setShouldDeleteAccount(shouldDelete); return this; } } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy