diff options
Diffstat (limited to 'gerrit-server/src/main/java/com/google/gerrit/server/project/DashboardsCollection.java')
-rw-r--r-- | gerrit-server/src/main/java/com/google/gerrit/server/project/DashboardsCollection.java | 233 |
1 files changed, 233 insertions, 0 deletions
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/DashboardsCollection.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/DashboardsCollection.java new file mode 100644 index 0000000000..a50e71c0fd --- /dev/null +++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/DashboardsCollection.java @@ -0,0 +1,233 @@ +// Copyright (C) 2012 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.project; + +import static com.google.gerrit.server.git.GitRepositoryManager.REFS_DASHBOARDS; + +import com.google.common.base.Joiner; +import com.google.common.base.Objects; +import com.google.common.base.Splitter; +import com.google.common.base.Strings; +import com.google.common.collect.Lists; +import com.google.gerrit.extensions.registration.DynamicMap; +import com.google.gerrit.extensions.restapi.AcceptsCreate; +import com.google.gerrit.extensions.restapi.ChildCollection; +import com.google.gerrit.extensions.restapi.IdString; +import com.google.gerrit.extensions.restapi.ResourceNotFoundException; +import com.google.gerrit.extensions.restapi.RestApiException; +import com.google.gerrit.extensions.restapi.RestModifyView; +import com.google.gerrit.extensions.restapi.RestView; +import com.google.gerrit.extensions.restapi.Url; +import com.google.gerrit.reviewdb.client.Project; +import com.google.gerrit.server.CurrentUser; +import com.google.gerrit.server.UrlEncoded; +import com.google.gerrit.server.git.GitRepositoryManager; +import com.google.gson.annotations.SerializedName; +import com.google.inject.Inject; +import com.google.inject.Provider; + +import org.eclipse.jgit.errors.AmbiguousObjectException; +import org.eclipse.jgit.errors.ConfigInvalidException; +import org.eclipse.jgit.errors.IncorrectObjectTypeException; +import org.eclipse.jgit.errors.RepositoryNotFoundException; +import org.eclipse.jgit.lib.BlobBasedConfig; +import org.eclipse.jgit.lib.Config; +import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.Repository; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.util.List; + +class DashboardsCollection implements + ChildCollection<ProjectResource, DashboardResource>, + AcceptsCreate<ProjectResource>{ + private final GitRepositoryManager gitManager; + private final DynamicMap<RestView<DashboardResource>> views; + private final Provider<ListDashboards> list; + private final Provider<SetDefaultDashboard.CreateDefault> createDefault; + + @Inject + DashboardsCollection(GitRepositoryManager gitManager, + DynamicMap<RestView<DashboardResource>> views, + Provider<ListDashboards> list, + Provider<SetDefaultDashboard.CreateDefault> createDefault) { + this.gitManager = gitManager; + this.views = views; + this.list = list; + this.createDefault = createDefault; + } + + @Override + public RestView<ProjectResource> list() throws ResourceNotFoundException { + return list.get(); + } + + @SuppressWarnings("unchecked") + @Override + public RestModifyView<ProjectResource, ?> create(ProjectResource parent, + IdString id) throws RestApiException { + if (id.equals("default")) { + return createDefault.get(); + } + throw new ResourceNotFoundException(id); + } + + @Override + public DashboardResource parse(ProjectResource parent, IdString id) + throws ResourceNotFoundException, IOException, ConfigInvalidException { + ProjectControl myCtl = parent.getControl(); + if (id.equals("default")) { + return DashboardResource.projectDefault(myCtl); + } + + List<String> parts = Lists.newArrayList( + Splitter.on(':').limit(2).split(id.get())); + if (parts.size() != 2) { + throw new ResourceNotFoundException(id); + } + + CurrentUser user = myCtl.getCurrentUser(); + String ref = parts.get(0); + String path = parts.get(1); + for (ProjectState ps : myCtl.getProjectState().tree()) { + try { + return parse(ps.controlFor(user), ref, path, myCtl); + } catch (AmbiguousObjectException e) { + throw new ResourceNotFoundException(id); + } catch (IncorrectObjectTypeException e) { + throw new ResourceNotFoundException(id); + } catch (ConfigInvalidException e) { + throw new ResourceNotFoundException(id); + } catch (ResourceNotFoundException e) { + continue; + } + } + throw new ResourceNotFoundException(id); + } + + private DashboardResource parse(ProjectControl ctl, String ref, String path, + ProjectControl myCtl) + throws ResourceNotFoundException, IOException, AmbiguousObjectException, + IncorrectObjectTypeException, ConfigInvalidException { + String id = ref + ":" + path; + if (!ref.startsWith(REFS_DASHBOARDS)) { + ref = REFS_DASHBOARDS + ref; + } + if (!Repository.isValidRefName(ref) + || !ctl.controlForRef(ref).canRead()) { + throw new ResourceNotFoundException(id); + } + + Repository git; + try { + git = gitManager.openRepository(ctl.getProject().getNameKey()); + } catch (RepositoryNotFoundException e) { + throw new ResourceNotFoundException(id); + } + try { + ObjectId objId = git.resolve(ref + ":" + path); + if (objId == null) { + throw new ResourceNotFoundException(id); + } + BlobBasedConfig cfg = new BlobBasedConfig(null, git, objId); + return new DashboardResource(myCtl, ref, path, cfg, false); + } finally { + git.close(); + } + } + + @Override + public DynamicMap<RestView<DashboardResource>> views() { + return views; + } + + static DashboardInfo parse(Project definingProject, String refName, + String path, Config config, String project, boolean setDefault) + throws UnsupportedEncodingException { + DashboardInfo info = new DashboardInfo(refName, path); + info.project = project; + info.definingProject = definingProject.getName(); + info.title = replace(project, config.getString("dashboard", null, "title")); + info.description = replace(project, config.getString("dashboard", null, "description")); + info.foreach = config.getString("dashboard", null, "foreach"); + + if (setDefault) { + String id = refName + ":" + path; + info.isDefault = id.equals(defaultOf(definingProject)) ? true : null; + } + + UrlEncoded u = new UrlEncoded("/dashboard/"); + u.put("title", Objects.firstNonNull(info.title, info.path)); + if (info.foreach != null) { + u.put("foreach", replace(project, info.foreach)); + } + for (String name : config.getSubsections("section")) { + Section s = new Section(); + s.name = name; + s.query = config.getString("section", name, "query"); + u.put(s.name, replace(project, s.query)); + info.sections.add(s); + } + info.url = u.toString().replace("%3A", ":"); + + return info; + } + + private static String replace(String project, String query) { + return query.replace("${project}", project); + } + + private static String defaultOf(Project proj) { + final String defaultId = Objects.firstNonNull( + proj.getLocalDefaultDashboard(), + Strings.nullToEmpty(proj.getDefaultDashboard())); + if (defaultId.startsWith(REFS_DASHBOARDS)) { + return defaultId.substring(REFS_DASHBOARDS.length()); + } else { + return defaultId; + } + } + + static class DashboardInfo { + final String kind = "gerritcodereview#dashboard"; + String id; + String project; + String definingProject; + String ref; + String path; + String description; + String foreach; + String url; + + @SerializedName("default") + Boolean isDefault; + + String title; + List<Section> sections = Lists.newArrayList(); + + DashboardInfo(String ref, String name) + throws UnsupportedEncodingException { + this.ref = ref; + this.path = name; + this.id = Joiner.on(':').join(Url.encode(ref), Url.encode(path)); + } + } + + static class Section { + String name; + String query; + } +} |