Enable storing of custom dashboards for projects
Custom dashboards can now be stored in the projects `refs/meta/dashboards/*` branches. A REST endpoint was added to retrieve the custom dashboards for a project. Change-Id: I1be4c4b8856f4edd279e752d5b4004f9a548bd2a Signed-off-by: Edwin Kempin <edwin.kempin@sap.com>
This commit is contained in:
		@@ -396,6 +396,35 @@ default. Optional fields are:
 | 
			
		||||
  ]
 | 
			
		||||
----
 | 
			
		||||
 | 
			
		||||
[[dashboards]]
 | 
			
		||||
/dashboards/project/ (List Dashboards)
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
Lists custom dashboards for a project.
 | 
			
		||||
 | 
			
		||||
The `/dashboards/project/` URL expects the project name as part of the
 | 
			
		||||
URL.
 | 
			
		||||
List all dashboards for the `myProject` project:
 | 
			
		||||
----
 | 
			
		||||
  GET /dashboards/project/myProject?format=JSON&d HTTP/1.0
 | 
			
		||||
 | 
			
		||||
  HTTP/1.1 200 OK
 | 
			
		||||
  Content-Disposition: attachment
 | 
			
		||||
  Content-Type: application/json;charset=UTF-8
 | 
			
		||||
 | 
			
		||||
  )]}'
 | 
			
		||||
  {
 | 
			
		||||
    "refs/meta/dashboards/main:MyDashboard": {
 | 
			
		||||
      "kind": "gerritcodereview#dashboard",
 | 
			
		||||
      "id" : "refs/meta/dashboards/main:MyDashboard",
 | 
			
		||||
      "dashboard_name": "MyDashboard",
 | 
			
		||||
      "ref_name": "refs/meta/dashboards/main",
 | 
			
		||||
      "project_name": "myProject",
 | 
			
		||||
      "description": "Most recent open and merged changes.",
 | 
			
		||||
      "parameters": "title\u003dMyDashboard\u0026Open+Changes\u003dstatus:open project:myProject limit:15\u0026Merged+Changes\u003dstatus:merged project:myProject limit:15"
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
----
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GERRIT
 | 
			
		||||
------
 | 
			
		||||
 
 | 
			
		||||
@@ -43,6 +43,40 @@ Parameters may be separated from each other using any of the following
 | 
			
		||||
characters, as some users may find one more readable than another:
 | 
			
		||||
`&` or `;` or `,`
 | 
			
		||||
 | 
			
		||||
Project Dashboards
 | 
			
		||||
------------------
 | 
			
		||||
 | 
			
		||||
It is possible to share custom dashboards at a project level. To do
 | 
			
		||||
this define the dashboards in a `refs/meta/dashboards/*` branch of the
 | 
			
		||||
project. For each dashboard create a config file. The file name will be
 | 
			
		||||
used as name for the dashboard.
 | 
			
		||||
 | 
			
		||||
Example dashboard config file `MyProject Dashboard`:
 | 
			
		||||
 | 
			
		||||
----
 | 
			
		||||
[main]
 | 
			
		||||
  description = Most recent open and merged changes.
 | 
			
		||||
[section "Open Changes"]
 | 
			
		||||
  query = status:open project:myProject limit:15
 | 
			
		||||
[section "Merged Changes"]
 | 
			
		||||
  query = status:merged project:myProject limit:15
 | 
			
		||||
----
 | 
			
		||||
 | 
			
		||||
Section main
 | 
			
		||||
~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
main.description::
 | 
			
		||||
+
 | 
			
		||||
The description of the dashboard.
 | 
			
		||||
 | 
			
		||||
Section section
 | 
			
		||||
~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
section.<name>.query::
 | 
			
		||||
+
 | 
			
		||||
The change query that should be used to populate the section with the
 | 
			
		||||
given name.
 | 
			
		||||
 | 
			
		||||
GERRIT
 | 
			
		||||
------
 | 
			
		||||
Part of link:index.html[Gerrit Code Review]
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,29 @@
 | 
			
		||||
// 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.client.dashboards;
 | 
			
		||||
 | 
			
		||||
import com.google.gwt.core.client.JavaScriptObject;
 | 
			
		||||
 | 
			
		||||
public class DashboardInfo extends JavaScriptObject {
 | 
			
		||||
  public final native String id() /*-{ return this.id; }-*/;
 | 
			
		||||
  public final native String name() /*-{ return this.dashboard_name; }-*/;
 | 
			
		||||
  public final native String refName() /*-{ return this.ref_name; }-*/;
 | 
			
		||||
  public final native String projectName() /*-{ return this.project_name; }-*/;
 | 
			
		||||
  public final native String description() /*-{ return this.description; }-*/;
 | 
			
		||||
  public final native String parameters() /*-{ return this.parameters; }-*/;
 | 
			
		||||
 | 
			
		||||
  protected DashboardInfo() {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,33 @@
 | 
			
		||||
// 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.client.dashboards;
 | 
			
		||||
 | 
			
		||||
import com.google.gerrit.client.rpc.NativeMap;
 | 
			
		||||
import com.google.gerrit.client.rpc.RestApi;
 | 
			
		||||
import com.google.gerrit.reviewdb.client.Project;
 | 
			
		||||
import com.google.gwtjsonrpc.common.AsyncCallback;
 | 
			
		||||
import com.google.gwt.http.client.URL;
 | 
			
		||||
 | 
			
		||||
/** Dashboards available from {@code /dashboards/}. */
 | 
			
		||||
public class DashboardMap extends NativeMap<DashboardInfo> {
 | 
			
		||||
  public static void allOnProject(Project.NameKey project,
 | 
			
		||||
      AsyncCallback<DashboardMap> callback) {
 | 
			
		||||
    new RestApi("/dashboards/project/" + URL.encode(project.get()).replaceAll("[?]", "%3F"))
 | 
			
		||||
        .send(NativeMap.copyKeysIntoChildren(callback));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  protected DashboardMap() {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -27,6 +27,7 @@ import com.google.gerrit.httpd.raw.ToolServlet;
 | 
			
		||||
import com.google.gerrit.httpd.rpc.account.AccountCapabilitiesServlet;
 | 
			
		||||
import com.google.gerrit.httpd.rpc.change.DeprecatedChangeQueryServlet;
 | 
			
		||||
import com.google.gerrit.httpd.rpc.change.ListChangesServlet;
 | 
			
		||||
import com.google.gerrit.httpd.rpc.dashboard.ListDashboardsServlet;
 | 
			
		||||
import com.google.gerrit.httpd.rpc.project.ListProjectsServlet;
 | 
			
		||||
import com.google.gerrit.reviewdb.client.Change;
 | 
			
		||||
import com.google.gerrit.reviewdb.client.Project;
 | 
			
		||||
@@ -97,6 +98,7 @@ class UrlModule extends ServletModule {
 | 
			
		||||
    serveRegex("^/(?:a/)?accounts/self/capabilities$").with(AccountCapabilitiesServlet.class);
 | 
			
		||||
    serveRegex("^/(?:a/)?changes/$").with(ListChangesServlet.class);
 | 
			
		||||
    serveRegex("^/(?:a/)?projects/(.*)?$").with(ListProjectsServlet.class);
 | 
			
		||||
    serveRegex("^/(?:a/)?dashboards/(.*)?$").with(ListDashboardsServlet.class);
 | 
			
		||||
 | 
			
		||||
    if (cfg.deprecatedQuery) {
 | 
			
		||||
      serve("/query").with(DeprecatedChangeQueryServlet.class);
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,75 @@
 | 
			
		||||
// 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.httpd.rpc.dashboard;
 | 
			
		||||
 | 
			
		||||
import com.google.common.base.Strings;
 | 
			
		||||
import com.google.gerrit.httpd.RestApiServlet;
 | 
			
		||||
import com.google.gerrit.server.CurrentUser;
 | 
			
		||||
import com.google.gerrit.server.OutputFormat;
 | 
			
		||||
import com.google.gerrit.server.dashboard.ListDashboards;
 | 
			
		||||
import com.google.inject.Inject;
 | 
			
		||||
import com.google.inject.Provider;
 | 
			
		||||
import com.google.inject.Singleton;
 | 
			
		||||
 | 
			
		||||
import java.io.ByteArrayOutputStream;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.net.URLDecoder;
 | 
			
		||||
 | 
			
		||||
import javax.servlet.http.HttpServletRequest;
 | 
			
		||||
import javax.servlet.http.HttpServletResponse;
 | 
			
		||||
 | 
			
		||||
@Singleton
 | 
			
		||||
public class ListDashboardsServlet extends RestApiServlet {
 | 
			
		||||
  private static final long serialVersionUID = 1L;
 | 
			
		||||
  private static final String PROJECT_LEVEL_PREFIX = "project/";
 | 
			
		||||
  private final ParameterParser paramParser;
 | 
			
		||||
  private final Provider<ListDashboards> factory;
 | 
			
		||||
 | 
			
		||||
  @Inject
 | 
			
		||||
  ListDashboardsServlet(final Provider<CurrentUser> currentUser,
 | 
			
		||||
      ParameterParser paramParser, Provider<ListDashboards> ls) {
 | 
			
		||||
    super(currentUser);
 | 
			
		||||
    this.paramParser = paramParser;
 | 
			
		||||
    this.factory = ls;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  protected void doGet(HttpServletRequest req, HttpServletResponse res)
 | 
			
		||||
      throws IOException {
 | 
			
		||||
    ListDashboards impl = factory.get();
 | 
			
		||||
    if (!Strings.isNullOrEmpty(req.getPathInfo())) {
 | 
			
		||||
      final String path = URLDecoder.decode(req.getPathInfo(), "UTF-8");
 | 
			
		||||
      if (path.startsWith(PROJECT_LEVEL_PREFIX)) {
 | 
			
		||||
        impl.setLevel(ListDashboards.Level.PROJECT);
 | 
			
		||||
        impl.setEntityName(path.substring(PROJECT_LEVEL_PREFIX.length()));
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    if (acceptsJson(req)) {
 | 
			
		||||
      impl.setFormat(OutputFormat.JSON_COMPACT);
 | 
			
		||||
    }
 | 
			
		||||
    if (paramParser.parse(impl, req, res)) {
 | 
			
		||||
      ByteArrayOutputStream buf = new ByteArrayOutputStream();
 | 
			
		||||
      if (impl.getFormat().isJson()) {
 | 
			
		||||
        res.setContentType(JSON_TYPE);
 | 
			
		||||
        buf.write(JSON_MAGIC);
 | 
			
		||||
      } else {
 | 
			
		||||
        res.setContentType("text/plain");
 | 
			
		||||
      }
 | 
			
		||||
      impl.display(buf);
 | 
			
		||||
      res.setCharacterEncoding("UTF-8");
 | 
			
		||||
      send(req, res, buf.toByteArray());
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -31,6 +31,7 @@ import com.google.gerrit.server.changedetail.DeleteDraftPatchSet;
 | 
			
		||||
import com.google.gerrit.server.changedetail.PublishDraft;
 | 
			
		||||
import com.google.gerrit.server.changedetail.RebaseChange;
 | 
			
		||||
import com.google.gerrit.server.changedetail.Submit;
 | 
			
		||||
import com.google.gerrit.server.dashboard.ListDashboards;
 | 
			
		||||
import com.google.gerrit.server.git.AsyncReceiveCommits;
 | 
			
		||||
import com.google.gerrit.server.git.BanCommit;
 | 
			
		||||
import com.google.gerrit.server.git.CreateCodeReviewNotes;
 | 
			
		||||
@@ -73,6 +74,7 @@ public class GerritRequestModule extends FactoryModule {
 | 
			
		||||
    bind(AccountResolver.class);
 | 
			
		||||
    bind(ChangeQueryRewriter.class);
 | 
			
		||||
    bind(ListProjects.class);
 | 
			
		||||
    bind(ListDashboards.class);
 | 
			
		||||
    bind(ApprovalsUtil.class);
 | 
			
		||||
 | 
			
		||||
    bind(PerRequestProjectControlCache.class).in(RequestScoped.class);
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,231 @@
 | 
			
		||||
// 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.dashboard;
 | 
			
		||||
 | 
			
		||||
import com.google.common.collect.Maps;
 | 
			
		||||
import com.google.gerrit.reviewdb.client.Project;
 | 
			
		||||
import com.google.gerrit.server.CurrentUser;
 | 
			
		||||
import com.google.gerrit.server.OutputFormat;
 | 
			
		||||
import com.google.gerrit.server.git.GitRepositoryManager;
 | 
			
		||||
import com.google.gerrit.server.project.ProjectCache;
 | 
			
		||||
import com.google.gerrit.server.project.ProjectControl;
 | 
			
		||||
import com.google.gerrit.server.project.ProjectState;
 | 
			
		||||
import com.google.gson.reflect.TypeToken;
 | 
			
		||||
import com.google.inject.Inject;
 | 
			
		||||
 | 
			
		||||
import org.eclipse.jgit.errors.ConfigInvalidException;
 | 
			
		||||
import org.eclipse.jgit.lib.Config;
 | 
			
		||||
import org.eclipse.jgit.lib.ObjectLoader;
 | 
			
		||||
import org.eclipse.jgit.lib.Ref;
 | 
			
		||||
import org.eclipse.jgit.lib.Repository;
 | 
			
		||||
import org.eclipse.jgit.revwalk.RevCommit;
 | 
			
		||||
import org.eclipse.jgit.revwalk.RevTree;
 | 
			
		||||
import org.eclipse.jgit.revwalk.RevWalk;
 | 
			
		||||
import org.eclipse.jgit.treewalk.TreeWalk;
 | 
			
		||||
import org.kohsuke.args4j.Option;
 | 
			
		||||
import org.slf4j.Logger;
 | 
			
		||||
import org.slf4j.LoggerFactory;
 | 
			
		||||
 | 
			
		||||
import java.io.BufferedWriter;
 | 
			
		||||
import java.io.ByteArrayOutputStream;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.OutputStream;
 | 
			
		||||
import java.io.OutputStreamWriter;
 | 
			
		||||
import java.io.PrintWriter;
 | 
			
		||||
import java.io.UnsupportedEncodingException;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 | 
			
		||||
/** List projects visible to the calling user. */
 | 
			
		||||
public class ListDashboards {
 | 
			
		||||
  private static final Logger log = LoggerFactory.getLogger(ListDashboards.class);
 | 
			
		||||
  private static String REFS_DASHBOARDS = "refs/meta/dashboards/";
 | 
			
		||||
 | 
			
		||||
  public static enum Level {
 | 
			
		||||
    PROJECT
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  private final CurrentUser currentUser;
 | 
			
		||||
  private final ProjectCache projectCache;
 | 
			
		||||
  private final GitRepositoryManager repoManager;
 | 
			
		||||
 | 
			
		||||
  @Option(name = "--format", metaVar = "FMT", usage = "Output display format")
 | 
			
		||||
  private OutputFormat format = OutputFormat.JSON;
 | 
			
		||||
 | 
			
		||||
  private Level level;
 | 
			
		||||
  private String entityName;
 | 
			
		||||
 | 
			
		||||
  @Inject
 | 
			
		||||
  protected ListDashboards(CurrentUser currentUser, ProjectCache projectCache,
 | 
			
		||||
      GitRepositoryManager repoManager) {
 | 
			
		||||
    this.currentUser = currentUser;
 | 
			
		||||
    this.projectCache = projectCache;
 | 
			
		||||
    this.repoManager = repoManager;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public OutputFormat getFormat() {
 | 
			
		||||
    return format;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public ListDashboards setFormat(OutputFormat fmt) {
 | 
			
		||||
    if (!format.isJson()) {
 | 
			
		||||
      throw new IllegalArgumentException(format.name() + " not supported");
 | 
			
		||||
    }
 | 
			
		||||
    this.format = fmt;
 | 
			
		||||
    return this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public ListDashboards setLevel(Level level) {
 | 
			
		||||
    this.level = level;
 | 
			
		||||
    return this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public ListDashboards setEntityName(String entityName) {
 | 
			
		||||
    this.entityName = entityName;
 | 
			
		||||
    return this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void display(OutputStream out) {
 | 
			
		||||
    final PrintWriter stdout;
 | 
			
		||||
    try {
 | 
			
		||||
      stdout = new PrintWriter(new BufferedWriter(new OutputStreamWriter(out, "UTF-8")));
 | 
			
		||||
    } catch (UnsupportedEncodingException e) {
 | 
			
		||||
      // Our encoding is required by the specifications for the runtime.
 | 
			
		||||
      throw new RuntimeException("JVM lacks UTF-8 encoding", e);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    try {
 | 
			
		||||
      final Map<String, DashboardInfo> dashboards;
 | 
			
		||||
      if (level != null) {
 | 
			
		||||
        switch (level) {
 | 
			
		||||
          case PROJECT:
 | 
			
		||||
            dashboards = projectDashboards(new Project.NameKey(entityName));
 | 
			
		||||
            break;
 | 
			
		||||
          default:
 | 
			
		||||
            throw new IllegalStateException("unsupported dashboard level: " + level);
 | 
			
		||||
        }
 | 
			
		||||
      } else {
 | 
			
		||||
        dashboards = Maps.newTreeMap();
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      format.newGson().toJson(dashboards,
 | 
			
		||||
          new TypeToken<Map<String, DashboardInfo>>() {}.getType(), stdout);
 | 
			
		||||
      stdout.print('\n');
 | 
			
		||||
    } finally {
 | 
			
		||||
      stdout.flush();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private Map<String, DashboardInfo> projectDashboards(final Project.NameKey projectName) {
 | 
			
		||||
    final Map<String, DashboardInfo> dashboards = Maps.newTreeMap();
 | 
			
		||||
 | 
			
		||||
    final ProjectState projectState = projectCache.get(projectName);
 | 
			
		||||
    final ProjectControl projectControl = projectState.controlFor(currentUser);
 | 
			
		||||
    if (projectState == null || !projectControl.isVisible()) {
 | 
			
		||||
      return dashboards;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Repository repo = null;
 | 
			
		||||
    RevWalk revWalk = null;
 | 
			
		||||
    try {
 | 
			
		||||
      repo = repoManager.openRepository(projectName);
 | 
			
		||||
      revWalk = new RevWalk(repo);
 | 
			
		||||
      final Map<String, Ref> refs = repo.getRefDatabase().getRefs(REFS_DASHBOARDS);
 | 
			
		||||
      for (final Ref ref : refs.values()) {
 | 
			
		||||
        if (projectControl.controlForRef(ref.getName()).canRead()) {
 | 
			
		||||
          dashboards.putAll(loadDashboards(projectName, repo, revWalk, ref));
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    } catch (IOException e) {
 | 
			
		||||
      log.warn("Failed to load dashboards of project " + projectName.get(), e);
 | 
			
		||||
    } finally {
 | 
			
		||||
      if (revWalk != null) {
 | 
			
		||||
        revWalk.release();
 | 
			
		||||
      }
 | 
			
		||||
      if (repo != null) {
 | 
			
		||||
        repo.close();
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return dashboards;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private Map<String, DashboardInfo> loadDashboards(
 | 
			
		||||
      final Project.NameKey projectName, final Repository repo,
 | 
			
		||||
      final RevWalk revWalk, final Ref ref) {
 | 
			
		||||
    final Map<String, DashboardInfo> dashboards = Maps.newTreeMap();
 | 
			
		||||
    TreeWalk treeWalk = new TreeWalk(repo);
 | 
			
		||||
    try {
 | 
			
		||||
      final RevCommit commit = revWalk.parseCommit(ref.getObjectId());
 | 
			
		||||
      final RevTree tree = commit.getTree();
 | 
			
		||||
      treeWalk.addTree(tree);
 | 
			
		||||
      treeWalk.setRecursive(true);
 | 
			
		||||
      while (treeWalk.next()) {
 | 
			
		||||
        DashboardInfo info = new DashboardInfo();
 | 
			
		||||
        info.dashboardName = treeWalk.getPathString();
 | 
			
		||||
        info.refName = ref.getName();
 | 
			
		||||
        info.projectName = projectName.get();
 | 
			
		||||
        info.id = createId(info.refName, info.dashboardName);
 | 
			
		||||
        final ObjectLoader loader = repo.open(treeWalk.getObjectId(0));
 | 
			
		||||
 | 
			
		||||
        ByteArrayOutputStream out = new ByteArrayOutputStream();
 | 
			
		||||
        loader.copyTo(out);
 | 
			
		||||
        Config dashboardConfig = new Config();
 | 
			
		||||
        dashboardConfig.fromText(new String(out.toByteArray(), "UTF-8"));
 | 
			
		||||
 | 
			
		||||
        info.description = dashboardConfig.getString("main", null, "description");
 | 
			
		||||
 | 
			
		||||
        final StringBuilder query = new StringBuilder();
 | 
			
		||||
        query.append("title=");
 | 
			
		||||
        query.append(info.dashboardName.replaceAll(" ", "+"));
 | 
			
		||||
        final Set<String> sections = dashboardConfig.getSubsections("section");
 | 
			
		||||
        for (final String section : sections) {
 | 
			
		||||
          query.append("&");
 | 
			
		||||
          query.append(section.replaceAll(" ", "+"));
 | 
			
		||||
          query.append("=");
 | 
			
		||||
          query.append(dashboardConfig.getString("section", section, "query"));
 | 
			
		||||
        }
 | 
			
		||||
        info.parameters = query.toString();
 | 
			
		||||
 | 
			
		||||
        dashboards.put(info.id, info);
 | 
			
		||||
      }
 | 
			
		||||
    } catch (IOException e) {
 | 
			
		||||
      log.warn("Failed to load dashboards of project " + projectName.get()
 | 
			
		||||
          + " from ref " + ref.getName(), e);
 | 
			
		||||
    } catch (ConfigInvalidException e) {
 | 
			
		||||
      log.warn("Failed to load dashboards of project " + projectName.get()
 | 
			
		||||
          + " from ref " + ref.getName(), e);
 | 
			
		||||
    } finally {
 | 
			
		||||
      treeWalk.release();
 | 
			
		||||
    }
 | 
			
		||||
    return dashboards;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private static String createId(final String refName,
 | 
			
		||||
      final String dashboardName) {
 | 
			
		||||
    return refName + ":" + dashboardName;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @SuppressWarnings("unused")
 | 
			
		||||
  private static class DashboardInfo {
 | 
			
		||||
    final String kind = "gerritcodereview#dashboard";
 | 
			
		||||
    String id;
 | 
			
		||||
    String dashboardName;
 | 
			
		||||
    String refName;
 | 
			
		||||
    String projectName;
 | 
			
		||||
    String description;
 | 
			
		||||
    String parameters;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user