| // 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.gerritforge.gerrit.globalrefdb.validation; |
| |
| import com.google.common.collect.ImmutableSet; |
| import com.google.inject.Inject; |
| import com.google.inject.assistedinject.Assisted; |
| import java.io.IOException; |
| import java.util.Collection; |
| import java.util.List; |
| import java.util.Map; |
| import org.eclipse.jgit.lib.BatchRefUpdate; |
| import org.eclipse.jgit.lib.Ref; |
| import org.eclipse.jgit.lib.RefDatabase; |
| import org.eclipse.jgit.lib.RefRename; |
| import org.eclipse.jgit.lib.RefUpdate; |
| |
| /** |
| * Wraps an instance of {@link RefDatabase} with the intent of wrapping {@link RefUpdate} operations |
| * to instances of {@link SharedRefDbRefUpdate} in order to allow validation of those operation |
| * against a shared ref-database before actually executing them. |
| */ |
| public class SharedRefDbRefDatabase extends RefDatabase { |
| private final SharedRefDbRefUpdate.Factory refUpdateFactory; |
| private final SharedRefDbBatchRefUpdate.Factory batchRefUpdateFactory; |
| private final String projectName; |
| private final RefDatabase refDatabase; |
| private final ImmutableSet<String> ignoredRefs; |
| |
| /** {@code SharedRefDbRefDatabase} Factory for Guice assisted injection. */ |
| public interface Factory { |
| SharedRefDbRefDatabase create( |
| String projectName, RefDatabase refDatabase, ImmutableSet<String> ignoredRefs); |
| } |
| |
| /** |
| * Constructs a {@code SharedRefDbRefDatabase} by wrapping an underlying refDatabase, so that |
| * update refs operations can be validated against a shared ref-database. |
| * |
| * @param refUpdateFactory a factory to provide a {@link SharedRefDbRefUpdate} |
| * @param batchRefUpdateFactory a factory to provide a {@link SharedRefDbBatchRefUpdate} |
| * @param projectName the name of the project to perform Git operations on |
| * @param refDatabase the wrapped {@link RefDatabase} |
| * @param ignoredRefs a set of reference for which ref-db validation should not be executed. |
| */ |
| @Inject |
| public SharedRefDbRefDatabase( |
| SharedRefDbRefUpdate.Factory refUpdateFactory, |
| SharedRefDbBatchRefUpdate.Factory batchRefUpdateFactory, |
| @Assisted String projectName, |
| @Assisted RefDatabase refDatabase, |
| @Assisted ImmutableSet<String> ignoredRefs) { |
| this.refUpdateFactory = refUpdateFactory; |
| this.batchRefUpdateFactory = batchRefUpdateFactory; |
| this.projectName = projectName; |
| this.refDatabase = refDatabase; |
| this.ignoredRefs = ignoredRefs; |
| } |
| |
| @Override |
| public int hashCode() { |
| return refDatabase.hashCode(); |
| } |
| |
| @Override |
| public boolean equals(Object obj) { |
| return refDatabase.equals(obj); |
| } |
| |
| @Override |
| public void create() throws IOException { |
| refDatabase.create(); |
| } |
| |
| @Override |
| public void close() { |
| refDatabase.close(); |
| } |
| |
| @Override |
| public boolean isNameConflicting(String name) throws IOException { |
| return refDatabase.isNameConflicting(name); |
| } |
| |
| @Override |
| public Collection<String> getConflictingNames(String name) throws IOException { |
| return refDatabase.getConflictingNames(name); |
| } |
| |
| /** |
| * Wrap a {@link RefUpdate} obtained by calling the underlying {@link RefDatabase} in a {@link |
| * SharedRefDbRefUpdate} |
| * |
| * @see RefDatabase#newUpdate(String, boolean) |
| * @throws java.io.IOException the reference cannot be accessed. |
| */ |
| @Override |
| public RefUpdate newUpdate(String name, boolean detach) throws IOException { |
| return wrapRefUpdate(refDatabase.newUpdate(name, detach)); |
| } |
| |
| @Override |
| public RefRename newRename(String fromName, String toName) throws IOException { |
| return refDatabase.newRename(fromName, toName); |
| } |
| |
| /** |
| * Obtains a {@link SharedRefDbBatchRefUpdate} via the {@code BatchRefUpdate.Factory} invoked on |
| * the underlying {@link RefDatabase}, so that batch updates can be validated against the shared |
| * ref-db. |
| * |
| * @see RefDatabase#newUpdate(String, boolean) |
| */ |
| @Override |
| public BatchRefUpdate newBatchUpdate() { |
| return batchRefUpdateFactory.create(projectName, refDatabase, ignoredRefs); |
| } |
| |
| @Override |
| public boolean performsAtomicTransactions() { |
| return refDatabase.performsAtomicTransactions(); |
| } |
| |
| @Override |
| public String toString() { |
| return refDatabase.toString(); |
| } |
| |
| @Override |
| public Ref exactRef(String name) throws IOException { |
| return refDatabase.exactRef(name); |
| } |
| |
| @Override |
| public Map<String, Ref> exactRef(String... refs) throws IOException { |
| return refDatabase.exactRef(refs); |
| } |
| |
| @Override |
| public Ref firstExactRef(String... refs) throws IOException { |
| return refDatabase.firstExactRef(refs); |
| } |
| |
| @Override |
| public List<Ref> getRefs() throws IOException { |
| return refDatabase.getRefs(); |
| } |
| |
| @SuppressWarnings("deprecation") |
| @Override |
| public Map<String, Ref> getRefs(String prefix) throws IOException { |
| return refDatabase.getRefs(prefix); |
| } |
| |
| @Override |
| public List<Ref> getRefsByPrefix(String prefix) throws IOException { |
| return refDatabase.getRefsByPrefix(prefix); |
| } |
| |
| @Override |
| public boolean hasRefs() throws IOException { |
| return refDatabase.hasRefs(); |
| } |
| |
| @Override |
| public List<Ref> getAdditionalRefs() throws IOException { |
| return refDatabase.getAdditionalRefs(); |
| } |
| |
| @Override |
| public Ref peel(Ref ref) throws IOException { |
| return refDatabase.peel(ref); |
| } |
| |
| @Override |
| public void refresh() { |
| refDatabase.refresh(); |
| } |
| |
| RefUpdate wrapRefUpdate(RefUpdate refUpdate) { |
| return refUpdateFactory.create(projectName, refUpdate, refDatabase, ignoredRefs); |
| } |
| } |