| // Copyright (C) 2008 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.client.data; |
| |
| import com.google.gerrit.client.reviewdb.Project; |
| import com.google.gerrit.client.reviewdb.ProjectRight; |
| import com.google.gerrit.client.reviewdb.ReviewDb; |
| import com.google.gerrit.client.rpc.Common; |
| import com.google.gwtorm.client.OrmException; |
| |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.LinkedHashMap; |
| import java.util.Map; |
| |
| /** Cache of project information, including access rights. */ |
| public class ProjectCache { |
| private final LinkedHashMap<Project.Id, Entry> byId = |
| new LinkedHashMap<Project.Id, Entry>(16, 0.75f, true) { |
| @Override |
| protected boolean removeEldestEntry( |
| final Map.Entry<Project.Id, ProjectCache.Entry> eldest) { |
| return 1024 <= size(); |
| } |
| }; |
| private final LinkedHashMap<Project.NameKey, Entry> byName = |
| new LinkedHashMap<Project.NameKey, Entry>(16, 0.75f, true) { |
| @Override |
| protected boolean removeEldestEntry( |
| final Map.Entry<Project.NameKey, ProjectCache.Entry> eldest) { |
| return 1024 <= size(); |
| } |
| }; |
| |
| /** Get the rights which are applied to all projects in the system. */ |
| public Collection<ProjectRight> getWildcardRights() { |
| return get(ProjectRight.WILD_PROJECT).getRights(); |
| } |
| |
| /** Invalidate the cached information about the given project. */ |
| public void invalidate(final Project p) { |
| if (p != null) { |
| synchronized (byName) { |
| byName.remove(p.getNameKey()); |
| } |
| synchronized (byId) { |
| byId.remove(p.getId()); |
| } |
| } |
| } |
| |
| /** Invalidate the cached information about the given project. */ |
| public void invalidate(final Project.Id projectId) { |
| if (projectId != null) { |
| final Entry e; |
| synchronized (byId) { |
| e = byId.remove(projectId); |
| } |
| if (e != null) { |
| synchronized (byName) { |
| byName.remove(e.getProject().getNameKey()); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Get the cached data for a project by its unique id. |
| * |
| * @param projectId id of the project. |
| * @return the cached data; null if no such project exists. |
| */ |
| public Entry get(final Project.Id projectId) { |
| if (projectId == null) { |
| return null; |
| } |
| |
| Entry m; |
| synchronized (byId) { |
| m = byId.get(projectId); |
| } |
| if (m != null) { |
| return m; |
| } |
| |
| try { |
| final ReviewDb db = Common.getSchemaFactory().open(); |
| try { |
| final Project p = db.projects().get(projectId); |
| if (p == null) { |
| return null; |
| } |
| m = new Entry(db, p); |
| } finally { |
| db.close(); |
| } |
| } catch (OrmException e) { |
| return null; |
| } |
| |
| synchronized (byName) { |
| byName.put(m.getProject().getNameKey(), m); |
| } |
| synchronized (byId) { |
| byId.put(m.getProject().getId(), m); |
| } |
| return m; |
| } |
| |
| /** |
| * Get the cached data for a project by its unique name. |
| * |
| * @param projectName name of the project. |
| * @return the cached data; null if no such project exists. |
| */ |
| public Entry get(final Project.NameKey projectName) { |
| if (projectName == null) { |
| return null; |
| } |
| |
| Entry m; |
| synchronized (byName) { |
| m = byName.get(projectName); |
| } |
| if (m != null) { |
| return m; |
| } |
| |
| try { |
| final ReviewDb db = Common.getSchemaFactory().open(); |
| try { |
| final Project p = db.projects().get(projectName); |
| if (p == null) { |
| return null; |
| } |
| m = new Entry(db, p); |
| } finally { |
| db.close(); |
| } |
| } catch (OrmException e) { |
| return null; |
| } |
| |
| synchronized (byName) { |
| byName.put(m.getProject().getNameKey(), m); |
| } |
| synchronized (byId) { |
| byId.put(m.getProject().getId(), m); |
| } |
| return m; |
| } |
| |
| /** Force the entire cache to flush from memory and recompute. */ |
| public void flush() { |
| synchronized (byId) { |
| byId.clear(); |
| } |
| synchronized (byName) { |
| byName.clear(); |
| } |
| } |
| |
| /** Cached information on a project. */ |
| public static class Entry { |
| private final Project project; |
| private final Collection<ProjectRight> rights; |
| |
| protected Entry(final ReviewDb db, final Project p) throws OrmException { |
| project = p; |
| rights = |
| Collections.unmodifiableCollection(db.projectRights().byProject( |
| project.getId()).toList()); |
| } |
| |
| public Project getProject() { |
| return project; |
| } |
| |
| public Collection<ProjectRight> getRights() { |
| return rights; |
| } |
| } |
| } |