| // Copyright (C) 2020 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.entities; | |
| import com.google.auto.value.AutoValue; | |
| import com.google.common.collect.ImmutableList; | |
| import com.google.common.collect.ImmutableMap; | |
| import com.google.common.collect.ImmutableSet; | |
| import com.google.common.collect.ImmutableSortedMap; | |
| import com.google.common.flogger.FluentLogger; | |
| import java.util.Collection; | |
| import java.util.List; | |
| import java.util.Map; | |
| import java.util.Optional; | |
| import org.eclipse.jgit.annotations.Nullable; | |
| import org.eclipse.jgit.errors.ConfigInvalidException; | |
| import org.eclipse.jgit.lib.ObjectId; | |
| /** | |
| * Cached representation of values parsed from {@link | |
| * com.google.gerrit.server.project.ProjectConfig}. | |
| * | |
| * <p>This class is immutable and thread-safe. | |
| */ | |
| @AutoValue | |
| public abstract class CachedProjectConfig { | |
| private static final FluentLogger logger = FluentLogger.forEnclosingClass(); | |
| public abstract Project getProject(); | |
| public abstract ImmutableMap<AccountGroup.UUID, GroupReference> getGroups(); | |
| /** Returns a set of all groups used by this configuration. */ | |
| public ImmutableSet<AccountGroup.UUID> getAllGroupUUIDs() { | |
| return getGroups().keySet(); | |
| } | |
| /** | |
| * Returns the group reference for a {@link AccountGroup.UUID}, if the group is used by at least | |
| * one rule. | |
| */ | |
| public Optional<GroupReference> getGroup(AccountGroup.UUID uuid) { | |
| return Optional.ofNullable(getGroups().get(uuid)); | |
| } | |
| /** | |
| * Returns the group reference for matching the given {@code name}, if the group is used by at | |
| * least one rule. | |
| */ | |
| public Optional<GroupReference> getGroupByName(@Nullable String name) { | |
| if (name == null) { | |
| return Optional.empty(); | |
| } | |
| return getGroups().values().stream().filter(g -> name.equals(g.getName())).findAny(); | |
| } | |
| /** Returns the account section containing visibility information about accounts. */ | |
| public abstract AccountsSection getAccountsSection(); | |
| /** Returns a map of {@link AccessSection}s keyed by their name. */ | |
| public abstract ImmutableSortedMap<String, AccessSection> getAccessSections(); | |
| /** Returns the {@link AccessSection} with to the given name. */ | |
| public Optional<AccessSection> getAccessSection(String refName) { | |
| return Optional.ofNullable(getAccessSections().get(refName)); | |
| } | |
| /** Returns all {@link AccessSection} names. */ | |
| public ImmutableSet<String> getAccessSectionNames() { | |
| return ImmutableSet.copyOf(getAccessSections().keySet()); | |
| } | |
| /** | |
| * Returns the {@link BranchOrderSection} containing the order in which branches should be shown. | |
| */ | |
| public abstract Optional<BranchOrderSection> getBranchOrderSection(); | |
| /** Returns the {@link ContributorAgreement}s keyed by their name. */ | |
| public abstract ImmutableMap<String, ContributorAgreement> getContributorAgreements(); | |
| /** Returns the {@link NotifyConfig}s keyed by their name. */ | |
| public abstract ImmutableMap<String, NotifyConfig> getNotifySections(); | |
| /** Returns the {@link LabelType}s keyed by their name. */ | |
| public abstract ImmutableMap<String, LabelType> getLabelSections(); | |
| /** Returns the {@link SubmitRequirement}s keyed by their name. */ | |
| public abstract ImmutableMap<String, SubmitRequirement> getSubmitRequirementSections(); | |
| /** Returns configured {@link ConfiguredMimeTypes}s. */ | |
| public abstract ConfiguredMimeTypes getMimeTypes(); | |
| /** Returns {@link SubscribeSection} keyed by the {@link Project.NameKey} they reference. */ | |
| public abstract ImmutableMap<Project.NameKey, SubscribeSection> getSubscribeSections(); | |
| /** Returns {@link StoredCommentLinkInfo} keyed by their name. */ | |
| public abstract ImmutableMap<String, StoredCommentLinkInfo> getCommentLinkSections(); | |
| /** Returns the blob ID of the {@code rules.pl} file, if present. */ | |
| public abstract Optional<ObjectId> getRulesId(); | |
| // TODO(hiesel): This should not have to be an Optional. | |
| /** Returns the SHA1 of the {@code refs/meta/config} branch. */ | |
| public abstract Optional<ObjectId> getRevision(); | |
| /** Returns the maximum allowed object size. */ | |
| public abstract long getMaxObjectSizeLimit(); | |
| /** Returns {@code true} if received objects should be checked for validity. */ | |
| public abstract boolean getCheckReceivedObjects(); | |
| /** Returns a list of panel sections keyed by title. */ | |
| public abstract ImmutableMap<String, ImmutableList<String>> getExtensionPanelSections(); | |
| public ImmutableList<SubscribeSection> getSubscribeSections(BranchNameKey branch) { | |
| return filterSubscribeSectionsByBranch(getSubscribeSections().values(), branch); | |
| } | |
| public abstract ImmutableMap<String, String> getPluginConfigs(); | |
| public abstract ImmutableMap<String, String> getProjectLevelConfigs(); | |
| public abstract ImmutableMap<String, ImmutableConfig> getParsedProjectLevelConfigs(); | |
| public static Builder builder() { | |
| return new AutoValue_CachedProjectConfig.Builder(); | |
| } | |
| public abstract Builder toBuilder(); | |
| @AutoValue.Builder | |
| public abstract static class Builder { | |
| public abstract Builder setProject(Project value); | |
| public abstract Builder setAccountsSection(AccountsSection value); | |
| public abstract Builder setBranchOrderSection(Optional<BranchOrderSection> value); | |
| public Builder addGroup(GroupReference groupReference) { | |
| groupsBuilder().put(groupReference.getUUID(), groupReference); | |
| return this; | |
| } | |
| public Builder addAccessSection(AccessSection accessSection) { | |
| accessSectionsBuilder().put(accessSection.getName(), accessSection); | |
| return this; | |
| } | |
| public Builder addContributorAgreement(ContributorAgreement contributorAgreement) { | |
| contributorAgreementsBuilder().put(contributorAgreement.getName(), contributorAgreement); | |
| return this; | |
| } | |
| public Builder addNotifySection(NotifyConfig notifyConfig) { | |
| notifySectionsBuilder().put(notifyConfig.getName(), notifyConfig); | |
| return this; | |
| } | |
| public Builder addLabelSection(LabelType labelType) { | |
| labelSectionsBuilder().put(labelType.getName(), labelType); | |
| return this; | |
| } | |
| public Builder addSubmitRequirementSection(SubmitRequirement submitRequirement) { | |
| submitRequirementSectionsBuilder().put(submitRequirement.name(), submitRequirement); | |
| return this; | |
| } | |
| public abstract Builder setMimeTypes(ConfiguredMimeTypes value); | |
| public Builder addSubscribeSection(SubscribeSection subscribeSection) { | |
| subscribeSectionsBuilder().put(subscribeSection.project(), subscribeSection); | |
| return this; | |
| } | |
| public Builder addCommentLinkSection(StoredCommentLinkInfo storedCommentLinkInfo) { | |
| commentLinkSectionsBuilder().put(storedCommentLinkInfo.getName(), storedCommentLinkInfo); | |
| return this; | |
| } | |
| public abstract Builder setRulesId(Optional<ObjectId> value); | |
| public abstract Builder setRevision(Optional<ObjectId> value); | |
| public abstract Builder setMaxObjectSizeLimit(long value); | |
| public abstract Builder setCheckReceivedObjects(boolean value); | |
| public abstract ImmutableMap.Builder<String, ImmutableList<String>> | |
| extensionPanelSectionsBuilder(); | |
| public Builder setExtensionPanelSections(Map<String, List<String>> value) { | |
| value | |
| .entrySet() | |
| .forEach( | |
| e -> | |
| extensionPanelSectionsBuilder() | |
| .put(e.getKey(), ImmutableList.copyOf(e.getValue()))); | |
| return this; | |
| } | |
| abstract ImmutableMap.Builder<String, String> pluginConfigsBuilder(); | |
| public Builder addPluginConfig(String pluginName, String pluginConfig) { | |
| pluginConfigsBuilder().put(pluginName, pluginConfig); | |
| return this; | |
| } | |
| abstract ImmutableMap.Builder<String, String> projectLevelConfigsBuilder(); | |
| abstract ImmutableMap.Builder<String, ImmutableConfig> parsedProjectLevelConfigsBuilder(); | |
| public Builder addProjectLevelConfig(String configFileName, String config) { | |
| projectLevelConfigsBuilder().put(configFileName, config); | |
| try { | |
| parsedProjectLevelConfigsBuilder().put(configFileName, ImmutableConfig.parse(config)); | |
| } catch (ConfigInvalidException e) { | |
| logger.atInfo().withCause(e).log("Config for %s not parsable", configFileName); | |
| } | |
| return this; | |
| } | |
| public abstract CachedProjectConfig build(); | |
| protected abstract ImmutableMap.Builder<AccountGroup.UUID, GroupReference> groupsBuilder(); | |
| protected abstract ImmutableSortedMap.Builder<String, AccessSection> accessSectionsBuilder(); | |
| protected abstract ImmutableMap.Builder<String, ContributorAgreement> | |
| contributorAgreementsBuilder(); | |
| protected abstract ImmutableMap.Builder<String, NotifyConfig> notifySectionsBuilder(); | |
| protected abstract ImmutableMap.Builder<String, LabelType> labelSectionsBuilder(); | |
| protected abstract ImmutableMap.Builder<String, SubmitRequirement> | |
| submitRequirementSectionsBuilder(); | |
| protected abstract ImmutableMap.Builder<Project.NameKey, SubscribeSection> | |
| subscribeSectionsBuilder(); | |
| protected abstract ImmutableMap.Builder<String, StoredCommentLinkInfo> | |
| commentLinkSectionsBuilder(); | |
| } | |
| private static ImmutableList<SubscribeSection> filterSubscribeSectionsByBranch( | |
| Collection<SubscribeSection> allSubscribeSections, BranchNameKey branch) { | |
| ImmutableList.Builder<SubscribeSection> ret = ImmutableList.builder(); | |
| for (SubscribeSection s : allSubscribeSections) { | |
| if (s.appliesTo(branch)) { | |
| ret.add(s); | |
| } | |
| } | |
| return ret.build(); | |
| } | |
| } |