// Copyright (C) 2010 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.schema; import com.google.gerrit.reviewdb.ApprovalCategory; import com.google.gerrit.reviewdb.Project; import com.google.gerrit.reviewdb.RefRight; import com.google.gerrit.reviewdb.ReviewDb; import com.google.gerrit.reviewdb.RefRight.RefPattern; import com.google.gerrit.server.project.RefControl.RefRightsForPattern; import com.google.gwtorm.client.OrmException; import com.google.inject.Inject; import com.google.inject.Provider; import java.util.ArrayList; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.TreeMap; public class Schema_34 extends SchemaVersion { private static final Comparator<String> DESCENDING_SORT = new Comparator<String>() { @Override public int compare(String a, String b) { int aLength = a.length(); int bLength = b.length(); if (bLength == aLength) { return a.compareTo(b); } return bLength - aLength; } }; @Inject Schema_34(Provider<Schema_33> prior) { super(prior); } @Override protected void migrateData(ReviewDb db, UpdateUI ui) throws OrmException { Iterable<Project> projects = db.projects().all(); boolean showedBanner = false; List<RefRight> toUpdate = new ArrayList<RefRight>(); List<RefRight> toDelete = new ArrayList<RefRight>(); for (Project p : projects) { boolean showedProject = false; List<RefRight> pr = db.refRights().byProject(p.getNameKey()).toList(); Map<ApprovalCategory.Id, Map<String, RefRightsForPattern>> r = new HashMap<ApprovalCategory.Id, Map<String, RefRightsForPattern>>(); for (RefRight right : pr) { ApprovalCategory.Id cat = right.getApprovalCategoryId(); if (r.get(cat) == null) { Map<String, RefRightsForPattern> m = new TreeMap<String, RefRightsForPattern>(DESCENDING_SORT); r.put(cat, m); } if (r.get(cat).get(right.getRefPattern()) == null) { RefRightsForPattern s = new RefRightsForPattern(); r.get(cat).put(right.getRefPattern(), s); } r.get(cat).get(right.getRefPattern()).addRight(right); } for (Map<String, RefRightsForPattern> categoryRights : r.values()) { for (RefRightsForPattern rrp : categoryRights.values()) { RefRight oldRight = rrp.getRights().get(0); if (shouldPrompt(oldRight)) { if (!showedBanner) { ui.message("Entering interactive reference rights migration tool..."); showedBanner = true; } if (!showedProject) { ui.message("In project " + p.getName()); showedProject = true; } ui.message("For category " + oldRight.getApprovalCategoryId()); boolean isWildcard = oldRight.getRefPattern().endsWith("/*"); boolean shouldUpdate = ui.yesno(!isWildcard, "Should rights for pattern " + oldRight.getRefPattern() + " be considered exclusive?"); if (shouldUpdate) { RefRight.Key newKey = new RefRight.Key(oldRight.getProjectNameKey(), new RefPattern("-" + oldRight.getRefPattern()), oldRight.getApprovalCategoryId(), oldRight.getAccountGroupId()); RefRight newRight = new RefRight(newKey); newRight.setMaxValue(oldRight.getMaxValue()); newRight.setMinValue(oldRight.getMinValue()); toUpdate.add(newRight); toDelete.add(oldRight); } } } } } db.refRights().insert(toUpdate); db.refRights().delete(toDelete); } private boolean shouldPrompt(RefRight right) { return !right.getRefPattern().equals("refs/*") && !right.getRefPattern().equals("refs/heads/*") && !right.getRefPattern().equals("refs/tags/*"); } }