Merge changes I35d41fd4,I4d6663cc,Iffc9bc99,Ie0621d78

* changes:
  Add Plugin web UI
  Add servlet to list plugins
  Apply @RequiresCapability to REST API
  Support JSON for plugin list command
This commit is contained in:
Martin Fick
2012-06-06 17:50:50 -07:00
committed by gerrit code review
36 changed files with 464 additions and 41 deletions

View File

@@ -40,6 +40,7 @@ public class PageLinks {
public static final String ADMIN_GROUPS = "/admin/groups/";
public static final String ADMIN_PROJECTS = "/admin/projects/";
public static final String ADMIN_CREATE_PROJECT = "/admin/create-project/";
public static final String ADMIN_PLUGINS = "/admin/plugins/";
public static String toChange(final ChangeInfo c) {
return toChange(c.getId());

View File

@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.sshd;
package com.google.gerrit.extensions.annotations;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@@ -21,7 +21,8 @@ import java.lang.annotation.Retention;
import java.lang.annotation.Target;
/**
* Annotation on {@link SshCommand} declaring a capability must be granted.
* Annotation on {@link SshCommand} or {@link RestApiServlet} declaring a
* capability must be granted.
*/
@Target({ElementType.TYPE})
@Retention(RUNTIME)

View File

@@ -17,6 +17,7 @@ package com.google.gerrit.client;
import static com.google.gerrit.common.PageLinks.ADMIN_CREATE_PROJECT;
import static com.google.gerrit.common.PageLinks.ADMIN_GROUPS;
import static com.google.gerrit.common.PageLinks.ADMIN_PROJECTS;
import static com.google.gerrit.common.PageLinks.ADMIN_PLUGINS;
import static com.google.gerrit.common.PageLinks.MINE;
import static com.google.gerrit.common.PageLinks.REGISTER;
import static com.google.gerrit.common.PageLinks.SETTINGS;
@@ -48,6 +49,7 @@ import com.google.gerrit.client.admin.AccountGroupMembersScreen;
import com.google.gerrit.client.admin.AccountGroupScreen;
import com.google.gerrit.client.admin.CreateProjectScreen;
import com.google.gerrit.client.admin.GroupListScreen;
import com.google.gerrit.client.admin.PluginListScreen;
import com.google.gerrit.client.admin.ProjectAccessScreen;
import com.google.gerrit.client.admin.ProjectBranchesScreen;
import com.google.gerrit.client.admin.ProjectInfoScreen;
@@ -621,6 +623,10 @@ public class Dispatcher {
} else if (matchPrefix("/admin/projects/", token)) {
Gerrit.display(token, selectProject());
} else if (matchPrefix(ADMIN_PLUGINS, token)
|| matchExact("/admin/plugins", token)) {
Gerrit.display(token, new PluginListScreen());
} else if (matchExact(ADMIN_CREATE_PROJECT, token)
|| matchExact("/admin/create-project", token)) {
Gerrit.display(token, new CreateProjectScreen());

View File

@@ -577,6 +577,7 @@ public class Gerrit implements EntryPoint {
m = new LinkMenuBar();
addLink(m, C.menuGroups(), PageLinks.ADMIN_GROUPS);
addLink(m, C.menuProjects(), PageLinks.ADMIN_PROJECTS);
addLink(m, C.menuPlugins(), PageLinks.ADMIN_PLUGINS);
menuLeft.add(m, C.menuAdmin());
}

View File

@@ -72,6 +72,7 @@ public interface GerritConstants extends Constants {
String menuPeople();
String menuGroups();
String menuProjects();
String menuPlugins();
String menuDocumentation();
String menuDocumentationIndex();

View File

@@ -55,6 +55,7 @@ menuAdmin = Admin
menuPeople = People
menuGroups = Groups
menuProjects = Projects
menuPlugins = Plugins
menuDocumentation = Documentation
menuDocumentationIndex = Index

View File

@@ -169,6 +169,7 @@ public interface GerritCss extends CssResource {
String patchSetUserIdentity();
String patchSizeCell();
String permalink();
String pluginsTable();
String posscore();
String projectAdminApprovalCategoryRangeLine();
String projectAdminApprovalCategoryValue();

View File

@@ -104,6 +104,12 @@ public interface AdminConstants extends Constants {
String projectAdminTabBranches();
String projectAdminTabAccess();
String plugins();
String pluginTabInstalled();
String columnPluginName();
String columnPluginVersion();
String noGroupSelected();
String errorNoMatchingGroups();
String errorNoGitRepository();

View File

@@ -84,6 +84,11 @@ projectAdminTabGeneral = General
projectAdminTabBranches = Branches
projectAdminTabAccess = Access
plugins = Plugins
pluginTabInstalled = Installed
columnPluginName = Plugin Name
columnPluginVersion = Version
noGroupSelected = (No group selected)
errorNoMatchingGroups = No Matching Groups
errorNoGitRepository = No Git Repository

View File

@@ -0,0 +1,92 @@
// 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.admin;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.plugins.PluginInfo;
import com.google.gerrit.client.plugins.PluginMap;
import com.google.gerrit.client.rpc.ScreenLoadCallback;
import com.google.gerrit.client.ui.FancyFlexTable;
import com.google.gwt.user.client.ui.FlexTable.FlexCellFormatter;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Panel;
public class PluginListScreen extends PluginScreen {
private Panel pluginPanel;
private PluginTable pluginTable;
@Override
protected void onInitUI() {
super.onInitUI();
initPluginList();
}
@Override
protected void onLoad() {
super.onLoad();
PluginMap.all(new ScreenLoadCallback<PluginMap>(this) {
@Override
protected void preDisplay(final PluginMap result) {
pluginTable.display(result);
}
});
}
private void initPluginList() {
pluginTable = new PluginTable();
pluginTable.addStyleName(Gerrit.RESOURCES.css().pluginsTable());
pluginPanel = new FlowPanel();
pluginPanel.setWidth("500px");
pluginPanel.add(pluginTable);
add(pluginPanel);
}
private class PluginTable extends FancyFlexTable<PluginInfo> {
PluginTable() {
table.setText(0, 1, Util.C.columnPluginName());
table.setText(0, 2, Util.C.columnPluginVersion());
final FlexCellFormatter fmt = table.getFlexCellFormatter();
fmt.addStyleName(0, 1, Gerrit.RESOURCES.css().dataHeader());
fmt.addStyleName(0, 2, Gerrit.RESOURCES.css().dataHeader());
}
void display(final PluginMap plugins) {
while (1 < table.getRowCount()) {
table.removeRow(table.getRowCount() - 1);
}
for (final PluginInfo p : plugins.values().asList()) {
final int row = table.getRowCount();
table.insertRow(row);
applyDataRowStyle(row);
populate(row, p);
}
}
void populate(final int row, final PluginInfo plugin) {
table.setText(row, 1, plugin.name());
table.setText(row, 2, plugin.version());
final FlexCellFormatter fmt = table.getFlexCellFormatter();
fmt.addStyleName(row, 1, Gerrit.RESOURCES.css().dataCell());
fmt.addStyleName(row, 2, Gerrit.RESOURCES.css().dataCell());
setRowItem(row, plugin);
}
}
}

View File

@@ -0,0 +1,35 @@
// 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.admin;
import static com.google.gerrit.common.PageLinks.ADMIN_PLUGINS;
import com.google.gerrit.client.ui.MenuScreen;
public abstract class PluginScreen extends MenuScreen {
public PluginScreen() {
setRequiresSignIn(true);
link(Util.C.pluginTabInstalled(), ADMIN_PLUGINS);
}
@Override
protected void onLoad() {
super.onLoad();
setPageTitle(Util.C.plugins());
display();
}
}

View File

@@ -1386,3 +1386,7 @@ a:hover.downloadLink {
font-style: italic;
padding: 2px 6px 1px;
}
/** PluginListScreen **/
.pluginsTable {
}

View File

@@ -0,0 +1,26 @@
// 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.plugins;
import com.google.gwt.core.client.JavaScriptObject;
public class PluginInfo extends JavaScriptObject {
public final native String name() /*-{ return this.name; }-*/;
public final native String version() /*-{ return this.version; }-*/;
protected PluginInfo() {
}
}

View File

@@ -0,0 +1,30 @@
// 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.plugins;
import com.google.gerrit.client.rpc.NativeMap;
import com.google.gerrit.client.rpc.RestApi;
import com.google.gwtjsonrpc.common.AsyncCallback;
/** Plugins available from {@code /plugins/}. */
public class PluginMap extends NativeMap<PluginInfo> {
public static void all(AsyncCallback<PluginMap> callback) {
new RestApi("/plugins/")
.send(NativeMap.copyKeysIntoChildren(callback));
}
protected PluginMap() {
}
}

View File

@@ -15,10 +15,14 @@
package com.google.gerrit.httpd;
import com.google.common.base.Strings;
import com.google.gerrit.extensions.annotations.RequiresCapability;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.account.CapabilityControl;
import com.google.gerrit.util.cli.CmdLineParser;
import com.google.gwtjsonrpc.server.RPCServletUtils;
import com.google.gwtjsonrpc.common.JsonConstants;
import com.google.gwtjsonrpc.server.RPCServletUtils;
import com.google.inject.Inject;
import com.google.inject.Provider;
import org.kohsuke.args4j.CmdLineException;
import org.slf4j.Logger;
@@ -62,12 +66,24 @@ public abstract class RestApiServlet extends HttpServlet {
}
}
private final Provider<CurrentUser> currentUser;
@Inject
protected RestApiServlet(final Provider<CurrentUser> currentUser) {
this.currentUser = currentUser;
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
noCache(res);
try {
checkRequiresCapability();
super.service(req, res);
} catch (RequireCapabilityException err) {
res.setStatus(HttpServletResponse.SC_FORBIDDEN);
noCache(res);
sendText(req, res, err.getMessage());
} catch (Error err) {
handleError(err, req, res);
} catch (RuntimeException err) {
@@ -75,6 +91,20 @@ public abstract class RestApiServlet extends HttpServlet {
}
}
private void checkRequiresCapability() throws RequireCapabilityException {
RequiresCapability rc = getClass().getAnnotation(RequiresCapability.class);
if (rc != null) {
CurrentUser user = currentUser.get();
CapabilityControl ctl = user.getCapabilities();
if (!ctl.canPerform(rc.value()) && !ctl.canAdministrateServer()) {
String msg = String.format(
"fatal: %s does not have \"%s\" capability.",
user.getUserName(), rc.value());
throw new RequireCapabilityException(msg);
}
}
}
private static void noCache(HttpServletResponse res) {
res.setHeader("Expires", "Fri, 01 Jan 1980 00:00:00 GMT");
res.setHeader("Pragma", "no-cache");
@@ -175,4 +205,11 @@ public abstract class RestApiServlet extends HttpServlet {
return true;
}
}
@SuppressWarnings("serial") // Never serialized or thrown out of this class.
private static class RequireCapabilityException extends Exception {
public RequireCapabilityException(String msg) {
super(msg);
}
}
}

View File

@@ -26,6 +26,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.plugin.ListPluginsServlet;
import com.google.gerrit.httpd.rpc.project.ListProjectsServlet;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
@@ -95,6 +96,7 @@ class UrlModule extends ServletModule {
filter("/a/*").through(RequireIdentifiedUserFilter.class);
serveRegex("^/(?:a/)?accounts/self/capabilities$").with(AccountCapabilitiesServlet.class);
serveRegex("^/(?:a/)?changes/$").with(ListChangesServlet.class);
serveRegex("^/(?:a/)?plugins/$").with(ListPluginsServlet.class);
serveRegex("^/(?:a/)?projects/(.*)?$").with(ListProjectsServlet.class);
if (cfg.deprecatedQuery) {

View File

@@ -58,8 +58,9 @@ public class AccountCapabilitiesServlet extends RestApiServlet {
private final Provider<Impl> factory;
@Inject
AccountCapabilitiesServlet(
AccountCapabilitiesServlet(final Provider<CurrentUser> currentUser,
ParameterParser paramParser, Provider<Impl> factory) {
super(currentUser);
this.paramParser = paramParser;
this.factory = factory;
}

View File

@@ -15,6 +15,7 @@
package com.google.gerrit.httpd.rpc.change;
import com.google.gerrit.httpd.RestApiServlet;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.OutputFormat;
import com.google.gerrit.server.query.QueryParseException;
import com.google.gerrit.server.query.change.ListChanges;
@@ -43,7 +44,9 @@ public class ListChangesServlet extends RestApiServlet {
private final Provider<ListChanges> factory;
@Inject
ListChangesServlet(ParameterParser paramParser, Provider<ListChanges> ls) {
ListChangesServlet(final Provider<CurrentUser> currentUser,
ParameterParser paramParser, Provider<ListChanges> ls) {
super(currentUser);
this.paramParser = paramParser;
this.factory = ls;
}

View File

@@ -0,0 +1,68 @@
// 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.plugin;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.extensions.annotations.RequiresCapability;
import com.google.gerrit.httpd.RestApiServlet;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.OutputFormat;
import com.google.gerrit.server.plugins.ListPlugins;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Singleton
@RequiresCapability(GlobalCapability.ADMINISTRATE_SERVER)
public class ListPluginsServlet extends RestApiServlet {
private static final long serialVersionUID = 1L;
private final ParameterParser paramParser;
private final Provider<ListPlugins> factory;
@Inject
ListPluginsServlet(final Provider<CurrentUser> currentUser,
ParameterParser paramParser, Provider<ListPlugins> ls) {
super(currentUser);
this.paramParser = paramParser;
this.factory = ls;
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse res)
throws IOException {
ListPlugins impl = factory.get();
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());
}
}
}

View File

@@ -16,6 +16,7 @@ package com.google.gerrit.httpd.rpc.project;
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.project.ListProjects;
import com.google.inject.Inject;
@@ -36,7 +37,9 @@ public class ListProjectsServlet extends RestApiServlet {
private final Provider<ListProjects> factory;
@Inject
ListProjectsServlet(ParameterParser paramParser, Provider<ListProjects> ls) {
ListProjectsServlet(final Provider<CurrentUser> currentUser,
ParameterParser paramParser, Provider<ListProjects> ls) {
super(currentUser);
this.paramParser = paramParser;
this.factory = ls;
}

View File

@@ -0,0 +1,107 @@
// 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.plugins;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.gerrit.server.OutputFormat;
import com.google.gson.reflect.TypeToken;
import com.google.inject.Inject;
import org.kohsuke.args4j.Option;
import java.io.BufferedWriter;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
/** List projects visible to the calling user. */
public class ListPlugins {
private final PluginLoader pluginLoader;
@Option(name = "--format", metaVar = "FMT", usage = "Output display format")
private OutputFormat format = OutputFormat.TEXT;
@Inject
protected ListPlugins(PluginLoader pluginLoader) {
this.pluginLoader = pluginLoader;
}
public OutputFormat getFormat() {
return format;
}
public ListPlugins setFormat(OutputFormat fmt) {
this.format = fmt;
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);
}
Map<String, PluginInfo> output = Maps.newTreeMap();
List<Plugin> plugins = Lists.newArrayList(pluginLoader.getPlugins());
Collections.sort(plugins, new Comparator<Plugin>() {
@Override
public int compare(Plugin a, Plugin b) {
return a.getName().compareTo(b.getName());
}
});
if (!format.isJson()) {
stdout.format("%-30s %-10s\n", "Name", "Version");
stdout
.print("----------------------------------------------------------------------\n");
}
for (Plugin p : plugins) {
PluginInfo info = new PluginInfo();
info.version = p.getVersion();
if (format.isJson()) {
output.put(p.getName(), info);
} else {
stdout.format("%-30s %-10s\n", p.getName(),
Strings.nullToEmpty(info.version));
}
}
if (format.isJson()) {
format.newGson().toJson(output,
new TypeToken<Map<String, PluginInfo>>() {}.getType(), stdout);
stdout.print('\n');
}
stdout.flush();
}
private static class PluginInfo {
String version;
}
}

View File

@@ -16,6 +16,7 @@ package com.google.gerrit.sshd;
import com.google.common.collect.Lists;
import com.google.common.util.concurrent.Atomics;
import com.google.gerrit.extensions.annotations.RequiresCapability;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.account.CapabilityControl;
import com.google.inject.Provider;

View File

@@ -16,6 +16,7 @@ package com.google.gerrit.sshd;
import com.google.common.collect.Sets;
import com.google.common.util.concurrent.Atomics;
import com.google.gerrit.extensions.annotations.RequiresCapability;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.account.CapabilityControl;
import com.google.gerrit.sshd.args4j.SubcommandHandler;

View File

@@ -15,8 +15,8 @@
package com.google.gerrit.sshd.commands;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.extensions.annotations.RequiresCapability;
import com.google.gerrit.sshd.AdminHighPriorityCommand;
import com.google.gerrit.sshd.RequiresCapability;
import com.google.gerrit.sshd.SshCommand;
import com.google.inject.Inject;

View File

@@ -15,6 +15,7 @@
package com.google.gerrit.sshd.commands;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.extensions.annotations.RequiresCapability;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.config.AllProjectsName;
import com.google.gerrit.server.git.MetaDataUpdate;
@@ -22,7 +23,6 @@ import com.google.gerrit.server.git.ProjectConfig;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectControl;
import com.google.gerrit.server.project.ProjectState;
import com.google.gerrit.sshd.RequiresCapability;
import com.google.gerrit.sshd.SshCommand;
import com.google.inject.Inject;

View File

@@ -16,6 +16,7 @@ package com.google.gerrit.sshd.commands;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.common.errors.InvalidSshKeyException;
import com.google.gerrit.extensions.annotations.RequiresCapability;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.AccountExternalId;
import com.google.gerrit.reviewdb.client.AccountGroup;
@@ -27,7 +28,6 @@ import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.AccountByEmailCache;
import com.google.gerrit.server.account.AccountCache;
import com.google.gerrit.server.ssh.SshKeyCache;
import com.google.gerrit.sshd.RequiresCapability;
import com.google.gerrit.sshd.SshCommand;
import com.google.gwtorm.server.OrmDuplicateKeyException;
import com.google.gwtorm.server.OrmException;

View File

@@ -17,10 +17,10 @@ package com.google.gerrit.sshd.commands;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.common.errors.NameAlreadyUsedException;
import com.google.gerrit.common.errors.PermissionDeniedException;
import com.google.gerrit.extensions.annotations.RequiresCapability;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.server.account.PerformCreateGroup;
import com.google.gerrit.sshd.RequiresCapability;
import com.google.gerrit.sshd.SshCommand;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;

View File

@@ -16,6 +16,7 @@ package com.google.gerrit.sshd.commands;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.common.errors.ProjectCreationFailedException;
import com.google.gerrit.extensions.annotations.RequiresCapability;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.Project.SubmitType;
@@ -23,7 +24,6 @@ import com.google.gerrit.server.project.CreateProject;
import com.google.gerrit.server.project.CreateProjectArgs;
import com.google.gerrit.server.project.ProjectControl;
import com.google.gerrit.server.project.SuggestParentCandidates;
import com.google.gerrit.sshd.RequiresCapability;
import com.google.gerrit.sshd.SshCommand;
import com.google.inject.Inject;

View File

@@ -16,9 +16,9 @@ package com.google.gerrit.sshd.commands;
import com.google.common.cache.Cache;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.extensions.annotations.RequiresCapability;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.sshd.BaseCommand;
import com.google.gerrit.sshd.RequiresCapability;
import com.google.inject.Inject;
import com.google.inject.Provider;

View File

@@ -15,11 +15,11 @@
package com.google.gerrit.sshd.commands;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.extensions.annotations.RequiresCapability;
import com.google.gerrit.server.git.WorkQueue;
import com.google.gerrit.server.git.WorkQueue.Task;
import com.google.gerrit.server.util.IdGenerator;
import com.google.gerrit.sshd.AdminHighPriorityCommand;
import com.google.gerrit.sshd.RequiresCapability;
import com.google.gerrit.sshd.SshCommand;
import com.google.inject.Inject;

View File

@@ -16,9 +16,9 @@ package com.google.gerrit.sshd.commands;
import com.google.common.base.Strings;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.extensions.annotations.RequiresCapability;
import com.google.gerrit.server.plugins.PluginInstallException;
import com.google.gerrit.server.plugins.PluginLoader;
import com.google.gerrit.sshd.RequiresCapability;
import com.google.gerrit.sshd.SshCommand;
import com.google.inject.Inject;

View File

@@ -14,39 +14,29 @@
package com.google.gerrit.sshd.commands;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.server.plugins.Plugin;
import com.google.gerrit.server.plugins.PluginLoader;
import com.google.gerrit.sshd.RequiresCapability;
import com.google.gerrit.sshd.SshCommand;
import com.google.gerrit.extensions.annotations.RequiresCapability;
import com.google.gerrit.server.plugins.ListPlugins;
import com.google.gerrit.sshd.BaseCommand;
import com.google.inject.Inject;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.apache.sshd.server.Environment;
import java.io.IOException;
@RequiresCapability(GlobalCapability.ADMINISTRATE_SERVER)
final class PluginLsCommand extends SshCommand {
final class PluginLsCommand extends BaseCommand {
@Inject
private PluginLoader loader;
private ListPlugins impl;
@Override
protected void run() {
List<Plugin> running = Lists.newArrayList(loader.getPlugins());
Collections.sort(running, new Comparator<Plugin>() {
public void start(Environment env) throws IOException {
startThread(new CommandRunnable() {
@Override
public int compare(Plugin a, Plugin b) {
return a.getName().compareTo(b.getName());
public void run() throws Exception {
parseCommandLine(impl);
impl.display(out);
}
});
stdout.format("%-30s %-10s\n", "Name", "Version");
stdout.print("----------------------------------------------------------------------\n");
for (Plugin p : running) {
stdout.format("%-30s %-10s\n", p.getName(),
Strings.nullToEmpty(p.getVersion()));
}
}
}

View File

@@ -17,8 +17,8 @@ package com.google.gerrit.sshd.commands;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.server.plugins.InvalidPluginException;
import com.google.gerrit.server.plugins.PluginInstallException;
import com.google.gerrit.extensions.annotations.RequiresCapability;
import com.google.gerrit.server.plugins.PluginLoader;
import com.google.gerrit.sshd.RequiresCapability;
import com.google.gerrit.sshd.SshCommand;
import com.google.inject.Inject;

View File

@@ -16,8 +16,8 @@ package com.google.gerrit.sshd.commands;
import com.google.common.collect.Sets;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.extensions.annotations.RequiresCapability;
import com.google.gerrit.server.plugins.PluginLoader;
import com.google.gerrit.sshd.RequiresCapability;
import com.google.gerrit.sshd.SshCommand;
import com.google.inject.Inject;

View File

@@ -19,12 +19,12 @@ import com.google.common.cache.CacheStats;
import com.google.common.collect.Maps;
import com.google.gerrit.common.Version;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.extensions.annotations.RequiresCapability;
import com.google.gerrit.extensions.events.LifecycleListener;
import com.google.gerrit.server.cache.h2.H2CacheImpl;
import com.google.gerrit.server.config.SitePath;
import com.google.gerrit.server.git.WorkQueue;
import com.google.gerrit.server.git.WorkQueue.Task;
import com.google.gerrit.sshd.RequiresCapability;
import com.google.gerrit.sshd.SshDaemon;
import com.google.inject.Inject;
import com.google.inject.Provider;

View File

@@ -15,10 +15,10 @@
package com.google.gerrit.sshd.commands;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.extensions.annotations.RequiresCapability;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.util.IdGenerator;
import com.google.gerrit.sshd.RequiresCapability;
import com.google.gerrit.sshd.SshCommand;
import com.google.gerrit.sshd.SshDaemon;
import com.google.gerrit.sshd.SshSession;