Merge "Add a BeanParseListener interface to DynamicOptions."
This commit is contained in:
@@ -63,7 +63,10 @@ class ParameterParser {
|
|||||||
T param, ListMultimap<String, String> in, HttpServletRequest req, HttpServletResponse res)
|
T param, ListMultimap<String, String> in, HttpServletRequest req, HttpServletResponse res)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
CmdLineParser clp = parserFactory.create(param);
|
CmdLineParser clp = parserFactory.create(param);
|
||||||
DynamicOptions.parse(dynamicBeans, clp, param);
|
DynamicOptions pluginOptions = new DynamicOptions(param, dynamicBeans);
|
||||||
|
pluginOptions.parseDynamicBeans(clp);
|
||||||
|
pluginOptions.setDynamicBeans();
|
||||||
|
pluginOptions.onBeanParseStart();
|
||||||
try {
|
try {
|
||||||
clp.parseOptionMap(in);
|
clp.parseOptionMap(in);
|
||||||
} catch (CmdLineException | NumberFormatException e) {
|
} catch (CmdLineException | NumberFormatException e) {
|
||||||
@@ -84,6 +87,7 @@ class ParameterParser {
|
|||||||
replyBinaryResult(req, res, BinaryResult.create(msg.toString()).setContentType("text/plain"));
|
replyBinaryResult(req, res, BinaryResult.create(msg.toString()).setContentType("text/plain"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
pluginOptions.onBeanParseEnd();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,11 @@ package com.google.gerrit.server;
|
|||||||
import com.google.gerrit.extensions.registration.DynamicMap;
|
import com.google.gerrit.extensions.registration.DynamicMap;
|
||||||
import com.google.gerrit.util.cli.CmdLineParser;
|
import com.google.gerrit.util.cli.CmdLineParser;
|
||||||
import com.google.inject.Provider;
|
import com.google.inject.Provider;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
/** Helper class to define and parse options from plugins on ssh and RestAPI commands. */
|
||||||
public class DynamicOptions {
|
public class DynamicOptions {
|
||||||
/**
|
/**
|
||||||
* To provide additional options, bind a DynamicBean. For example:
|
* To provide additional options, bind a DynamicBean. For example:
|
||||||
@@ -43,6 +47,16 @@ public class DynamicOptions {
|
|||||||
*/
|
*/
|
||||||
public interface DynamicBean {}
|
public interface DynamicBean {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implement this if your DynamicBean needs an opportunity to act on the Bean directly before or
|
||||||
|
* after argument parsing.
|
||||||
|
*/
|
||||||
|
public interface BeanParseListener extends DynamicBean {
|
||||||
|
void onBeanParseStart(String plugin, Object bean);
|
||||||
|
|
||||||
|
void onBeanParseEnd(String plugin, Object bean);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The entity which provided additional options may need a way to receive a reference to the
|
* The entity which provided additional options may need a way to receive a reference to the
|
||||||
* DynamicBean it provided. To do so, the existing class should implement BeanReceiver (a setter)
|
* DynamicBean it provided. To do so, the existing class should implement BeanReceiver (a setter)
|
||||||
@@ -66,32 +80,67 @@ public class DynamicOptions {
|
|||||||
void setDynamicBean(String plugin, DynamicBean dynamicBean);
|
void setDynamicBean(String plugin, DynamicBean dynamicBean);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Object bean;
|
||||||
|
Map<String, DynamicBean> beansByPlugin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* To include options from DynamicBeans, setup a DynamicMap and call this parse method. For
|
* Internal: For Gerrit to include options from DynamicBeans, setup a DynamicMap and instantiate
|
||||||
* example:
|
* this class so the following methods can be called if desired:
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* DynamicMap.mapOf(binder(), DynamicOptions.DynamicBean.class);
|
* DynamicOptions pluginOptions = new DynamicOptions(bean, dynamicBeans);
|
||||||
|
* pluginOptions.parseDynamicBeans(clp);
|
||||||
|
* pluginOptions.setDynamicBeans();
|
||||||
|
* pluginOptions.onBeanParseStart();
|
||||||
*
|
*
|
||||||
* ...
|
* // parse arguments here: clp.parseArgument(argv);
|
||||||
*
|
*
|
||||||
* protected void parseCommandLine(Object options) throws UnloggedFailure {
|
* pluginOptions.onBeanParseEnd();
|
||||||
* final CmdLineParser clp = newCmdLineParser(options);
|
|
||||||
* DynamicOptions.parse(dynamicBeans, clp, options);
|
|
||||||
* ...
|
|
||||||
* }
|
|
||||||
* </pre>
|
* </pre>
|
||||||
*/
|
*/
|
||||||
public static void parse(DynamicMap<DynamicBean> dynamicBeans, CmdLineParser clp, Object bean) {
|
public DynamicOptions(Object bean, DynamicMap<DynamicBean> dynamicBeans) {
|
||||||
|
this.bean = bean;
|
||||||
|
beansByPlugin = new HashMap<String, DynamicBean>();
|
||||||
for (String plugin : dynamicBeans.plugins()) {
|
for (String plugin : dynamicBeans.plugins()) {
|
||||||
Provider<DynamicBean> provider =
|
Provider<DynamicBean> provider =
|
||||||
dynamicBeans.byPlugin(plugin).get(bean.getClass().getCanonicalName());
|
dynamicBeans.byPlugin(plugin).get(bean.getClass().getCanonicalName());
|
||||||
if (provider != null) {
|
if (provider != null) {
|
||||||
DynamicBean dynamicBean = provider.get();
|
beansByPlugin.put(plugin, provider.get());
|
||||||
clp.parseWithPrefix(plugin, dynamicBean);
|
}
|
||||||
if (bean instanceof BeanReceiver) {
|
}
|
||||||
((BeanReceiver) bean).setDynamicBean(plugin, dynamicBean);
|
}
|
||||||
}
|
|
||||||
|
public void parseDynamicBeans(CmdLineParser clp) {
|
||||||
|
for (Entry<String, DynamicBean> e : beansByPlugin.entrySet()) {
|
||||||
|
clp.parseWithPrefix(e.getKey(), e.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDynamicBeans() {
|
||||||
|
if (bean instanceof BeanReceiver) {
|
||||||
|
BeanReceiver receiver = (BeanReceiver) bean;
|
||||||
|
for (Entry<String, DynamicBean> e : beansByPlugin.entrySet()) {
|
||||||
|
receiver.setDynamicBean(e.getKey(), e.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onBeanParseStart() {
|
||||||
|
for (Entry<String, DynamicBean> e : beansByPlugin.entrySet()) {
|
||||||
|
DynamicBean instance = e.getValue();
|
||||||
|
if (instance instanceof BeanParseListener) {
|
||||||
|
BeanParseListener listener = (BeanParseListener) instance;
|
||||||
|
listener.onBeanParseStart(e.getKey(), bean);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onBeanParseEnd() {
|
||||||
|
for (Entry<String, DynamicBean> e : beansByPlugin.entrySet()) {
|
||||||
|
DynamicBean instance = e.getValue();
|
||||||
|
if (instance instanceof BeanParseListener) {
|
||||||
|
BeanParseListener listener = (BeanParseListener) instance;
|
||||||
|
listener.onBeanParseEnd(e.getKey(), bean);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -197,7 +197,10 @@ public abstract class BaseCommand implements Command {
|
|||||||
*/
|
*/
|
||||||
protected void parseCommandLine(Object options) throws UnloggedFailure {
|
protected void parseCommandLine(Object options) throws UnloggedFailure {
|
||||||
final CmdLineParser clp = newCmdLineParser(options);
|
final CmdLineParser clp = newCmdLineParser(options);
|
||||||
DynamicOptions.parse(dynamicBeans, clp, options);
|
DynamicOptions pluginOptions = new DynamicOptions(options, dynamicBeans);
|
||||||
|
pluginOptions.parseDynamicBeans(clp);
|
||||||
|
pluginOptions.setDynamicBeans();
|
||||||
|
pluginOptions.onBeanParseStart();
|
||||||
try {
|
try {
|
||||||
clp.parseArgument(argv);
|
clp.parseArgument(argv);
|
||||||
} catch (IllegalArgumentException | CmdLineException err) {
|
} catch (IllegalArgumentException | CmdLineException err) {
|
||||||
@@ -212,6 +215,7 @@ public abstract class BaseCommand implements Command {
|
|||||||
msg.write(usage());
|
msg.write(usage());
|
||||||
throw new UnloggedFailure(1, msg.toString());
|
throw new UnloggedFailure(1, msg.toString());
|
||||||
}
|
}
|
||||||
|
pluginOptions.onBeanParseEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String usage() {
|
protected String usage() {
|
||||||
|
|||||||
Reference in New Issue
Block a user