Line data Source code
1 : // Copyright (C) 2011 The Android Open Source Project 2 : // 3 : // Licensed under the Apache License, Version 2.0 (the "License"); 4 : // you may not use this file except in compliance with the License. 5 : // You may obtain a copy of the License at 6 : // 7 : // http://www.apache.org/licenses/LICENSE-2.0 8 : // 9 : // Unless required by applicable law or agreed to in writing, software 10 : // distributed under the License is distributed on an "AS IS" BASIS, 11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 : // See the License for the specific language governing permissions and 13 : // limitations under the License. 14 : 15 : package com.google.gerrit.server.rules; 16 : 17 : import com.google.gerrit.entities.Account; 18 : import com.google.gerrit.entities.Change; 19 : import com.google.gerrit.entities.PatchSet; 20 : import com.google.gerrit.entities.Project; 21 : import com.google.gerrit.exceptions.StorageException; 22 : import com.google.gerrit.server.AnonymousUser; 23 : import com.google.gerrit.server.IdentifiedUser; 24 : import com.google.gerrit.server.PatchSetUtil; 25 : import com.google.gerrit.server.account.AccountCache; 26 : import com.google.gerrit.server.account.Accounts; 27 : import com.google.gerrit.server.account.Emails; 28 : import com.google.gerrit.server.config.PluginConfigFactory; 29 : import com.google.gerrit.server.git.GitRepositoryManager; 30 : import com.google.gerrit.server.patch.DiffNotAvailableException; 31 : import com.google.gerrit.server.patch.DiffOperations; 32 : import com.google.gerrit.server.patch.DiffOptions; 33 : import com.google.gerrit.server.patch.filediff.FileDiffOutput; 34 : import com.google.gerrit.server.permissions.PermissionBackend; 35 : import com.google.gerrit.server.project.ProjectState; 36 : import com.google.gerrit.server.query.change.ChangeData; 37 : import com.googlecode.prolog_cafe.exceptions.SystemException; 38 : import com.googlecode.prolog_cafe.lang.Prolog; 39 : import java.io.IOException; 40 : import java.util.HashMap; 41 : import java.util.Map; 42 : import org.eclipse.jgit.lib.Repository; 43 : import org.eclipse.jgit.revwalk.RevCommit; 44 : 45 : public final class StoredValues { 46 104 : public static final StoredValue<Accounts> ACCOUNTS = StoredValue.create(Accounts.class); 47 104 : public static final StoredValue<AccountCache> ACCOUNT_CACHE = 48 104 : StoredValue.create(AccountCache.class); 49 104 : public static final StoredValue<Emails> EMAILS = StoredValue.create(Emails.class); 50 104 : public static final StoredValue<ChangeData> CHANGE_DATA = StoredValue.create(ChangeData.class); 51 104 : public static final StoredValue<ProjectState> PROJECT_STATE = 52 104 : StoredValue.create(ProjectState.class); 53 : 54 : public static Change getChange(Prolog engine) throws SystemException { 55 4 : ChangeData cd = CHANGE_DATA.get(engine); 56 : try { 57 4 : return cd.change(); 58 0 : } catch (StorageException e) { 59 0 : throw new SystemException( 60 0 : String.format("Cannot load change %s: %s", cd.getId(), e.getMessage())); 61 : } 62 : } 63 : 64 : public static PatchSet getPatchSet(Prolog engine) throws SystemException { 65 5 : ChangeData cd = CHANGE_DATA.get(engine); 66 : try { 67 5 : return cd.currentPatchSet(); 68 0 : } catch (StorageException e) { 69 0 : throw new SystemException(e.getMessage()); 70 : } 71 : } 72 : 73 104 : public static final StoredValue<RevCommit> COMMIT = 74 104 : new StoredValue<>() { 75 : @Override 76 : public RevCommit createValue(Prolog engine) { 77 4 : Change change = getChange(engine); 78 4 : PatchSet ps = getPatchSet(engine); 79 4 : PrologEnvironment env = (PrologEnvironment) engine.control; 80 4 : PatchSetUtil patchSetUtil = env.getArgs().getPatchsetUtil(); 81 : try { 82 4 : return patchSetUtil.getRevCommit(change.getProject(), ps); 83 0 : } catch (IOException e) { 84 0 : throw new SystemException(e.getMessage()); 85 : } 86 : } 87 : }; 88 : 89 104 : public static final StoredValue<Map<String, FileDiffOutput>> DIFF_LIST = 90 104 : new StoredValue<>() { 91 : @Override 92 : public Map<String, FileDiffOutput> createValue(Prolog engine) { 93 2 : PrologEnvironment env = (PrologEnvironment) engine.control; 94 2 : PatchSet ps = getPatchSet(engine); 95 2 : DiffOperations diffOperations = env.getArgs().getDiffOperations(); 96 2 : Change change = getChange(engine); 97 2 : Project.NameKey project = change.getProject(); 98 : Map<String, FileDiffOutput> diffList; 99 : try { 100 2 : diffList = 101 2 : diffOperations.listModifiedFilesAgainstParent( 102 2 : project, ps.commitId(), /* parentNum= */ 0, DiffOptions.DEFAULTS); 103 0 : } catch (DiffNotAvailableException e) { 104 0 : throw new SystemException( 105 0 : String.format( 106 : "Cannot create modified files for project %s, commit Id %s: %s", 107 0 : project, ps.commitId(), e.getMessage())); 108 2 : } 109 2 : return diffList; 110 : } 111 : }; 112 : 113 : // Accessing GitRepositoryManager could be slow. 114 : // It should be minimized or cached to reduce pause time 115 : // when evaluating Prolog submit rules. 116 104 : public static final StoredValue<GitRepositoryManager> REPO_MANAGER = 117 104 : new StoredValue<>() { 118 : @Override 119 : public GitRepositoryManager createValue(Prolog engine) { 120 0 : PrologEnvironment env = (PrologEnvironment) engine.control; 121 0 : return env.getArgs().getGitRepositoryManager(); 122 : } 123 : }; 124 : 125 104 : public static final StoredValue<PluginConfigFactory> PLUGIN_CONFIG_FACTORY = 126 104 : new StoredValue<>() { 127 : @Override 128 : public PluginConfigFactory createValue(Prolog engine) { 129 0 : PrologEnvironment env = (PrologEnvironment) engine.control; 130 0 : return env.getArgs().getPluginConfigFactory(); 131 : } 132 : }; 133 : 134 104 : public static final StoredValue<Repository> REPOSITORY = 135 104 : new StoredValue<>() { 136 : @Override 137 : public Repository createValue(Prolog engine) { 138 2 : PrologEnvironment env = (PrologEnvironment) engine.control; 139 2 : GitRepositoryManager gitMgr = env.getArgs().getGitRepositoryManager(); 140 2 : Change change = getChange(engine); 141 2 : Project.NameKey projectKey = change.getProject(); 142 : Repository repo; 143 : try { 144 2 : repo = gitMgr.openRepository(projectKey); 145 0 : } catch (IOException e) { 146 0 : throw new SystemException(e.getMessage()); 147 2 : } 148 2 : env.addToCleanup(repo::close); 149 2 : return repo; 150 : } 151 : }; 152 : 153 104 : public static final StoredValue<PermissionBackend> PERMISSION_BACKEND = 154 104 : new StoredValue<>() { 155 : @Override 156 : protected PermissionBackend createValue(Prolog engine) { 157 0 : PrologEnvironment env = (PrologEnvironment) engine.control; 158 0 : return env.getArgs().getPermissionBackend(); 159 : } 160 : }; 161 : 162 104 : public static final StoredValue<AnonymousUser> ANONYMOUS_USER = 163 104 : new StoredValue<>() { 164 : @Override 165 : protected AnonymousUser createValue(Prolog engine) { 166 0 : PrologEnvironment env = (PrologEnvironment) engine.control; 167 0 : return env.getArgs().getAnonymousUser(); 168 : } 169 : }; 170 : 171 104 : public static final StoredValue<Map<Account.Id, IdentifiedUser>> USERS = 172 104 : new StoredValue<>() { 173 : @Override 174 : protected Map<Account.Id, IdentifiedUser> createValue(Prolog engine) { 175 0 : return new HashMap<>(); 176 : } 177 : }; 178 : 179 : private StoredValues() {} 180 : }