Add top level /config REST API

/config/server/ part is hard coded for now, but we may add more
config specific resource names later.

/config/server/capabilities retrieves the known server wide
capabilities list. The list has to be loaded dynamically from
the server to permit plugins to declare their own capabilities.

Change-Id: I83692bd021925d37659bfbc88b3e3b67b92c18c1
This commit is contained in:
David Ostrovsky
2013-06-09 02:16:57 +02:00
committed by Shawn Pearce
parent 665c2a88d3
commit 28b8ea6f9e
23 changed files with 628 additions and 64 deletions

View File

@@ -0,0 +1,123 @@
Gerrit Code Review - /config/ REST API
======================================
This page describes the config related REST endpoints.
Please also take note of the general information on the
link:rest-api.html[REST API].
[[config-endpoints]]
Config Endpoints
---------------
[[list-capabilities]]
List Capabilities
~~~~~~~~~~~~~~~~~
[verse]
'GET /config/server/capabilities'
Lists the capabilities that are available in system. There are two kinds of
capabilities: core and plugin-owned capabilities.
As result a map is returned that maps the capability names to
capability descriptions. The entries in the map are sorted
by capability name.
.Request
----
GET /config/server/capabilities/ HTTP/1.0
----
.Response
----
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
)]}'
{
"accessDatabase": {
"kind": "gerritcodereview#capability",
"id": "accessDatabase",
"name": "Access Database"
},
"administrateServer": {
"kind": "gerritcodereview#capability",
"id": "administrateServer",
"name": "Administrate Server"
},
"createAccount": {
"kind": "gerritcodereview#capability",
"id": "createAccount",
"name": "Create Account"
},
"createGroup": {
"kind": "gerritcodereview#capability",
"id": "createGroup",
"name": "Create Group"
},
"createProject": {
"kind": "gerritcodereview#capability",
"id": "createProject",
"name": "Create Project"
},
"emailReviewers": {
"kind": "gerritcodereview#capability",
"id": "emailReviewers",
"name": "Email Reviewers"
},
"flushCaches": {
"kind": "gerritcodereview#capability",
"id": "flushCaches",
"name": "Flush Caches"
},
"killTask": {
"kind": "gerritcodereview#capability",
"id": "killTask",
"name": "Kill Task"
},
"priority": {
"kind": "gerritcodereview#capability",
"id": "priority",
"name": "Priority"
},
"queryLimit": {
"kind": "gerritcodereview#capability",
"id": "queryLimit",
"name": "Query Limit"
},
"runGC": {
"kind": "gerritcodereview#capability",
"id": "runGC",
"name": "Run Garbage Collection"
},
"startReplication": {
"kind": "gerritcodereview#capability",
"id": "startReplication",
"name": "Start Replication"
},
"streamEvents": {
"kind": "gerritcodereview#capability",
"id": "streamEvents",
"name": "Stream Events"
},
"viewCaches": {
"kind": "gerritcodereview#capability",
"id": "viewCaches",
"name": "View Caches"
},
"viewConnections": {
"kind": "gerritcodereview#capability",
"id": "viewConnections",
"name": "View Connections"
},
"viewQueue": {
"kind": "gerritcodereview#capability",
"id": "viewQueue",
"name": "View Queue"
}
}
----
GERRIT
------
Part of link:index.html[Gerrit Code Review]

View File

@@ -13,6 +13,8 @@ link:rest-api-accounts.html[/accounts/]::
Account related REST endpoints
link:rest-api-changes.html[/changes/]::
Change related REST endpoints
link:rest-api-config.html[/config/]::
Config related REST endpoints
link:rest-api-groups.html[/groups/]::
Group related REST endpoints
link:rest-api-projects.html[/projects/]::

View File

@@ -17,6 +17,7 @@ package com.google.gerrit.common.data;
import com.google.gerrit.reviewdb.client.Project;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class ProjectAccess {
@@ -28,6 +29,7 @@ public class ProjectAccess {
protected boolean isConfigVisible;
protected boolean canUpload;
protected LabelTypes labelTypes;
protected Map<String, String> capabilities;
public ProjectAccess() {
}
@@ -112,4 +114,12 @@ public class ProjectAccess {
public void setLabelTypes(LabelTypes labelTypes) {
this.labelTypes = labelTypes;
}
public Map<String, String> getCapabilities() {
return capabilities;
}
public void setCapabilities(Map<String, String> capabilities) {
this.capabilities = capabilities;
}
}

View File

@@ -93,9 +93,8 @@ public class AccessSectionEditor extends Composite implements
public AccessSectionEditor(ProjectAccess access) {
projectAccess = access;
permissionSelector =
new ValueListBox<String>(PermissionNameRenderer.INSTANCE);
permissionSelector = new ValueListBox<String>(
new PermissionNameRenderer(access.getCapabilities()));
permissionSelector.addValueChangeHandler(new ValueChangeHandler<String>() {
@Override
public void onValueChange(ValueChangeEvent<String> event) {
@@ -222,7 +221,7 @@ public class AccessSectionEditor extends Composite implements
List<String> perms = new ArrayList<String>();
if (AccessSection.GLOBAL_CAPABILITIES.equals(value.getName())) {
for (String varName : Util.C.capabilityNames().keySet()) {
for (String varName : projectAccess.getCapabilities().keySet()) {
addPermission(varName, perms);
}
} else if (RefConfigSection.isValid(value.getName())) {
@@ -282,7 +281,7 @@ public class AccessSectionEditor extends Composite implements
@Override
public PermissionEditor create(int index) {
PermissionEditor subEditor =
new PermissionEditor(projectAccess.getProjectName(), readOnly, value,
new PermissionEditor(projectAccess, readOnly, value,
projectAccess.getLabelTypes());
permissionContainer.insert(subEditor, index);
return subEditor;

View File

@@ -125,8 +125,6 @@ public interface AdminConstants extends Constants {
String refErrorPrintable();
String errorsMustBeFixed();
Map<String, String> capabilityNames();
String sectionTypeReference();
String sectionTypeSection();
Map<String, String> sectionNames();

View File

@@ -144,43 +144,6 @@ refErrorNoSpace = References cannot contain spaces
refErrorPrintable = References may contain only printable characters
errorsMustBeFixed = Errors must be fixed before committing changes.
# Capability Names
capabilityNames = \
accessDatabase, \
administrateServer, \
createAccount, \
createGroup, \
createProject, \
emailReviewers, \
flushCaches, \
killTask, \
priority, \
queryLimit, \
runAs, \
runGC, \
startReplication, \
streamEvents, \
viewCaches, \
viewConnections, \
viewQueue
accessDatabase = Access Database
administrateServer = Administrate Server
createAccount = Create Account
createGroup = Create Group
createProject = Create Project
emailReviewers = Email Reviewers
flushCaches = Flush Caches
killTask = Kill Task
priority = Priority
queryLimit = Query Limit
runAs = Run As
runGC = Run Garbage Collection
startReplication = Start Replication
streamEvents = Stream Events
viewCaches = View Caches
viewConnections = View Connections
viewQueue = View Queue
# Section Names
sectionTypeReference = Reference:
sectionTypeSection = Section:

View File

@@ -24,6 +24,7 @@ import com.google.gerrit.common.data.LabelTypes;
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.common.data.PermissionRange;
import com.google.gerrit.common.data.PermissionRule;
import com.google.gerrit.common.data.ProjectAccess;
import com.google.gerrit.common.data.RefConfigSection;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.core.client.GWT;
@@ -107,17 +108,19 @@ public class PermissionEditor extends Composite implements Editor<Permission>,
private PermissionRange.WithDefaults validRange;
private boolean isDeleted;
public PermissionEditor(Project.NameKey projectName,
public PermissionEditor(ProjectAccess projectAccess,
boolean readOnly,
AccessSection section,
LabelTypes labelTypes) {
this.readOnly = readOnly;
this.section = section;
this.projectName = projectName;
this.projectName = projectAccess.getProjectName();
this.labelTypes = labelTypes;
normalName = new ValueLabel<String>(PermissionNameRenderer.INSTANCE);
deletedName = new ValueLabel<String>(PermissionNameRenderer.INSTANCE);
PermissionNameRenderer nameRenderer =
new PermissionNameRenderer(projectAccess.getCapabilities());
normalName = new ValueLabel<String>(nameRenderer);
deletedName = new ValueLabel<String>(nameRenderer);
initWidget(uiBinder.createAndBindUi(this));
groupToAdd.setProject(projectName);

View File

@@ -22,33 +22,48 @@ import java.util.HashMap;
import java.util.Map;
class PermissionNameRenderer implements Renderer<String> {
static final PermissionNameRenderer INSTANCE = new PermissionNameRenderer();
private static final Map<String, String> all;
private static final Map<String, String> permissions;
static {
all = new HashMap<String, String>();
for (Map.Entry<String, String> e : Util.C.capabilityNames().entrySet()) {
all.put(e.getKey(), e.getValue());
all.put(e.getKey().toLowerCase(), e.getValue());
}
permissions = new HashMap<String, String>();
for (Map.Entry<String, String> e : Util.C.permissionNames().entrySet()) {
all.put(e.getKey(), e.getValue());
all.put(e.getKey().toLowerCase(), e.getValue());
permissions.put(e.getKey(), e.getValue());
permissions.put(e.getKey().toLowerCase(), e.getValue());
}
}
private final Map<String, String> fromServer;
PermissionNameRenderer(Map<String, String> allFromOutside) {
fromServer = allFromOutside;
}
@Override
public String render(String varName) {
if (Permission.isLabel(varName)) {
return Util.M.label(new Permission(varName).getLabel());
}
String desc = all.get(varName);
if (desc == null) {
desc = all.get(varName.toLowerCase());
String desc = permissions.get(varName);
if (desc != null) {
return desc;
}
return desc != null ? desc : varName;
desc = fromServer.get(varName);
if (desc != null) {
return desc;
}
desc = permissions.get(varName.toLowerCase());
if (desc != null) {
return desc;
}
desc = fromServer.get(varName.toLowerCase());
if (desc != null) {
return desc;
}
return varName;
}
@Override

View File

@@ -18,7 +18,12 @@ import static com.google.gerrit.common.ProjectAccessUtil.mergeSections;
import static com.google.gerrit.common.ProjectAccessUtil.removeEmptyPermissionsAndSections;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.config.CapabilityInfo;
import com.google.gerrit.client.config.ConfigServerApi;
import com.google.gerrit.client.rpc.CallbackGroup;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.rpc.NativeMap;
import com.google.gerrit.client.rpc.Natives;
import com.google.gerrit.client.rpc.ScreenLoadCallback;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.common.data.AccessSection;
@@ -33,6 +38,7 @@ import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.Label;
@@ -41,8 +47,10 @@ import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwtexpui.globalkey.client.NpTextArea;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class ProjectAccessScreen extends ProjectScreen {
@@ -90,6 +98,8 @@ public class ProjectAccessScreen extends ProjectScreen {
private ProjectAccess access;
private NativeMap<CapabilityInfo> capabilityMap;
public ProjectAccessScreen(final Project.NameKey toShow) {
super(toShow);
}
@@ -107,18 +117,36 @@ public class ProjectAccessScreen extends ProjectScreen {
@Override
protected void onLoad() {
super.onLoad();
CallbackGroup cbs = new CallbackGroup();
ConfigServerApi.capabilities(
cbs.add(new AsyncCallback<NativeMap<CapabilityInfo>>() {
@Override
public void onSuccess(NativeMap<CapabilityInfo> result) {
capabilityMap = result;
}
@Override
public void onFailure(Throwable caught) {
// Handled by ScreenLoadCallback.onFailure().
}
}));
Util.PROJECT_SVC.projectAccess(getProjectKey(),
new ScreenLoadCallback<ProjectAccess>(this) {
cbs.addGwtjsonrpc(new ScreenLoadCallback<ProjectAccess>(this) {
@Override
public void preDisplay(ProjectAccess access) {
displayReadOnly(access);
}
});
}));
savedPanel = ACCESS;
}
private void displayReadOnly(ProjectAccess access) {
this.access = access;
Map<String, String> allCapabilities = new HashMap<String, String>();
for (CapabilityInfo c : Natives.asList(capabilityMap.values())) {
allCapabilities.put(c.id(), c.name());
}
this.access.setCapabilities(allCapabilities);
accessEditor.setEditing(false);
UIObject.setVisible(editTools, !access.getOwnerOf().isEmpty() || access.canUpload());
edit.setEnabled(!access.getOwnerOf().isEmpty() || access.canUpload());

View File

@@ -0,0 +1,25 @@
// Copyright (C) 2013 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.config;
import com.google.gwt.core.client.JavaScriptObject;
public class CapabilityInfo extends JavaScriptObject {
public final native String id() /*-{ return this.id; }-*/;
public final native String name() /*-{ return this.name; }-*/;
protected CapabilityInfo() {
}
}

View File

@@ -0,0 +1,30 @@
// Copyright (C) 2013 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.config;
import com.google.gerrit.client.rpc.NativeMap;
import com.google.gerrit.client.rpc.RestApi;
import com.google.gwt.user.client.rpc.AsyncCallback;
/**
* A collection of static methods which work on the Gerrit REST API for server
* configuration.
*/
public class ConfigServerApi {
/** map of the server wide capabilities (core & plugins). */
public static void capabilities(AsyncCallback<NativeMap<CapabilityInfo>> cb) {
new RestApi("/config/server/capabilities/").get(cb);
}
}

View File

@@ -27,6 +27,7 @@ import com.google.gerrit.httpd.raw.ToolServlet;
import com.google.gerrit.httpd.rpc.account.AccountsRestApiServlet;
import com.google.gerrit.httpd.rpc.change.ChangesRestApiServlet;
import com.google.gerrit.httpd.rpc.change.DeprecatedChangeQueryServlet;
import com.google.gerrit.httpd.rpc.config.ConfigRestApiServlet;
import com.google.gerrit.httpd.rpc.group.GroupsRestApiServlet;
import com.google.gerrit.httpd.rpc.project.ProjectsRestApiServlet;
import com.google.gerrit.reviewdb.client.Change;
@@ -102,6 +103,7 @@ class UrlModule extends ServletModule {
serveRegex("^/(?:a/)?tools/(.*)$").with(ToolServlet.class);
serveRegex("^/(?:a/)?accounts/(.*)$").with(AccountsRestApiServlet.class);
serveRegex("^/(?:a/)?changes/(.*)$").with(ChangesRestApiServlet.class);
serveRegex("^/(?:a/)?config/(.*)$").with(ConfigRestApiServlet.class);
serveRegex("^/(?:a/)?groups/(.*)?$").with(GroupsRestApiServlet.class);
serveRegex("^/(?:a/)?projects/(.*)?$").with(ProjectsRestApiServlet.class);

View File

@@ -0,0 +1,32 @@
// Copyright (C) 2013 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.config;
import com.google.gerrit.httpd.restapi.RestApiServlet;
import com.google.gerrit.server.config.ConfigCollection;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
@Singleton
public class ConfigRestApiServlet extends RestApiServlet {
private static final long serialVersionUID = 1L;
@Inject
ConfigRestApiServlet(RestApiServlet.Globals globals,
Provider<ConfigCollection> configCollection) {
super(globals, configCollection);
}
}

View File

@@ -0,0 +1,52 @@
// Copyright (C) 2013 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.config;
import com.google.gerrit.extensions.registration.DynamicMap;
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.RestView;
import com.google.inject.Inject;
import com.google.inject.Provider;
public class CapabilitiesCollection implements
ChildCollection<ConfigResource, CapabilityResource> {
private final DynamicMap<RestView<CapabilityResource>> views;
private final Provider<ListCapabilities> list;
@Inject
CapabilitiesCollection(DynamicMap<RestView<CapabilityResource>> views,
Provider<ListCapabilities> list) {
this.views = views;
this.list = list;
}
@Override
public RestView<ConfigResource> list() throws ResourceNotFoundException {
return list.get();
}
@Override
public CapabilityResource parse(ConfigResource parent, IdString id)
throws ResourceNotFoundException {
throw new ResourceNotFoundException(id);
}
@Override
public DynamicMap<RestView<CapabilityResource>> views() {
return views;
}
}

View File

@@ -0,0 +1,42 @@
// Copyright (C) 2013 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.config;
import org.eclipse.jgit.nls.NLS;
import org.eclipse.jgit.nls.TranslationBundle;
public class CapabilityConstants extends TranslationBundle {
public static CapabilityConstants get() {
return NLS.getBundleFor(CapabilityConstants.class);
}
public String accessDatabase;
public String administrateServer;
public String createAccount;
public String createGroup;
public String createProject;
public String emailReviewers;
public String flushCaches;
public String killTask;
public String priority;
public String queryLimit;
public String runAs;
public String runGC;
public String startReplication;
public String streamEvents;
public String viewCaches;
public String viewConnections;
public String viewQueue;
}

View File

@@ -0,0 +1,23 @@
// Copyright (C) 2013 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.config;
import com.google.gerrit.extensions.restapi.RestView;
import com.google.inject.TypeLiteral;
public class CapabilityResource extends ConfigResource {
public static final TypeLiteral<RestView<CapabilityResource>> CAPABILITY_KIND =
new TypeLiteral<RestView<CapabilityResource>>() {};
}

View File

@@ -0,0 +1,52 @@
// Copyright (C) 2013 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.config;
import com.google.gerrit.extensions.registration.DynamicMap;
import com.google.gerrit.extensions.restapi.IdString;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.extensions.restapi.RestCollection;
import com.google.gerrit.extensions.restapi.RestView;
import com.google.gerrit.extensions.restapi.TopLevelResource;
import com.google.inject.Inject;
public class ConfigCollection implements
RestCollection<TopLevelResource, ConfigResource> {
private final DynamicMap<RestView<ConfigResource>> views;
@Inject
ConfigCollection(DynamicMap<RestView<ConfigResource>> views) {
this.views = views;
}
@Override
public RestView<TopLevelResource> list() throws ResourceNotFoundException {
throw new ResourceNotFoundException();
}
@Override
public DynamicMap<RestView<ConfigResource>> views() {
return views;
}
@Override
public ConfigResource parse(TopLevelResource root, IdString id)
throws ResourceNotFoundException {
if (id.equals("server")) {
return new ConfigResource();
}
throw new ResourceNotFoundException(id);
}
}

View File

@@ -0,0 +1,24 @@
// Copyright (C) 2013 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.config;
import com.google.gerrit.extensions.restapi.RestResource;
import com.google.gerrit.extensions.restapi.RestView;
import com.google.inject.TypeLiteral;
public class ConfigResource implements RestResource {
public static final TypeLiteral<RestView<ConfigResource>> CONFIG_KIND =
new TypeLiteral<RestView<ConfigResource>>() {};
}

View File

@@ -240,6 +240,7 @@ public class GerritGlobalModule extends FactoryModule {
install(new AuditModule());
install(new com.google.gerrit.server.account.Module());
install(new com.google.gerrit.server.change.Module());
install(new com.google.gerrit.server.config.Module());
install(new com.google.gerrit.server.group.Module());
install(new com.google.gerrit.server.project.Module());

View File

@@ -0,0 +1,54 @@
// Copyright (C) 2013 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.config;
import com.google.common.collect.Maps;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.extensions.restapi.RestReadView;
import java.util.Map;
/** List capabilities visible to the calling user. */
public class ListCapabilities implements RestReadView<ConfigResource> {
@Override
public Map<String, CapabilityInfo> apply(ConfigResource resource)
throws AuthException, BadRequestException, ResourceConflictException,
IllegalArgumentException, SecurityException, IllegalAccessException,
NoSuchFieldException {
Map<String, CapabilityInfo> output = Maps.newTreeMap();
Class<? extends CapabilityConstants> bundleClass =
CapabilityConstants.get().getClass();
CapabilityConstants c = CapabilityConstants.get();
for (String id : GlobalCapability.getAllNames()) {
String name = (String) bundleClass.getField(id).get(c);
output.put(id, new CapabilityInfo(id, name));
}
return output;
}
public static class CapabilityInfo {
final String kind = "gerritcodereview#capability";
public String id;
public String name;
public CapabilityInfo(String id, String name) {
this.id = id;
this.name = name;
}
}
}

View File

@@ -0,0 +1,30 @@
// Copyright (C) 2013 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.config;
import static com.google.gerrit.server.config.ConfigResource.CONFIG_KIND;
import static com.google.gerrit.server.config.CapabilityResource.CAPABILITY_KIND;
import com.google.gerrit.extensions.registration.DynamicMap;
import com.google.gerrit.extensions.restapi.RestApiModule;
public class Module extends RestApiModule {
@Override
protected void configure() {
DynamicMap.mapOf(binder(), CONFIG_KIND);
DynamicMap.mapOf(binder(), CAPABILITY_KIND);
child(CONFIG_KIND, "capabilities").to(CapabilitiesCollection.class);
}
}

View File

@@ -0,0 +1,17 @@
accessDatabase = Access Database
administrateServer = Administrate Server
createAccount = Create Account
createGroup = Create Group
createProject = Create Project
emailReviewers = Email Reviewers
flushCaches = Flush Caches
killTask = Kill Task
priority = Priority
queryLimit = Query Limit
runAs = Run As
runGC = Run Garbage Collection
startReplication = Start Replication
streamEvents = Stream Events
viewCaches = View Caches
viewConnections = View Connections
viewQueue = View Queue

View File

@@ -0,0 +1,39 @@
// Copyright (C) 2013 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.config;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.server.config.ListCapabilities.CapabilityInfo;
import org.junit.Test;
import java.util.Map;
public class ListCapabilitiesTest {
@Test
public void testList() throws Exception {
Map<String, CapabilityInfo> m =
new ListCapabilities().apply(new ConfigResource());
for (String id : GlobalCapability.getAllNames()) {
assertTrue("contains " + id, m.containsKey(id));
assertEquals(id, m.get(id).id);
assertNotNull(id + " has name", m.get(id).name);
}
}
}