Allow plugins to define 'has' search operands.
Create a ChangeHasOperandFactory interface which extends a more generic ChangeOperandFactory in the ChangeQueryBuilder class along with support methods and enhancements to support defining has operands that will be called from the 'has' operator in the ChangeQueryBuilder class. Change-Id: I9014b0094a9d79c2cbcafb0dcd375fbb93a46748
This commit is contained in:

committed by
Martin Fick

parent
01d42968a5
commit
dba4e892b1
@@ -684,6 +684,43 @@ public class SampleOperator
|
||||
}
|
||||
----
|
||||
|
||||
[[search_operands]]
|
||||
=== Search Operands ===
|
||||
|
||||
Plugins can define new search operands to extend change searching.
|
||||
Plugin methods implementing search operands (returning a
|
||||
`Predicate<ChangeData>`), must be defined on a class implementing
|
||||
one of the `ChangeQueryBuilder.ChangeOperandsFactory` interfaces
|
||||
(.e.g., ChangeQueryBuilder.ChangeHasOperandFactory). The specific
|
||||
`ChangeOperandFactory` class must also be bound to the `DynamicSet` from
|
||||
a module's `configure()` method in the plugin.
|
||||
|
||||
The new operand, when used in a search would appear as:
|
||||
operatorName:operandName_pluginName
|
||||
|
||||
A sample `ChangeHasOperandFactory` class implementing, and registering, a
|
||||
new `has:sample_pluginName` operand is shown below:
|
||||
|
||||
====
|
||||
@Singleton
|
||||
public class SampleHasOperand implements ChangeHasOperandFactory {
|
||||
public static class Module extends AbstractModule {
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(ChangeHasOperandFactory.class)
|
||||
.annotatedWith(Exports.named("sample")
|
||||
.to(SampleHasOperand.class);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Predicate<ChangeData> create(ChangeQueryBuilder builder)
|
||||
throws QueryParseException {
|
||||
return new HasSamplePredicate();
|
||||
}
|
||||
====
|
||||
|
||||
|
||||
[[simple-configuration]]
|
||||
== Simple Configuration in `gerrit.config`
|
||||
|
||||
|
@@ -376,6 +376,7 @@ public class GerritGlobalModule extends FactoryModule {
|
||||
DynamicSet.setOf(binder(), UploadValidationListener.class);
|
||||
|
||||
DynamicMap.mapOf(binder(), ChangeQueryBuilder.ChangeOperatorFactory.class);
|
||||
DynamicMap.mapOf(binder(), ChangeQueryBuilder.ChangeHasOperandFactory.class);
|
||||
install(new GitwebConfig.LegacyModule(cfg));
|
||||
|
||||
bind(AnonymousUser.class);
|
||||
|
@@ -28,6 +28,7 @@ import com.google.gerrit.common.data.GroupReference;
|
||||
import com.google.gerrit.common.data.SubmitRecord;
|
||||
import com.google.gerrit.common.errors.NotSignedInException;
|
||||
import com.google.gerrit.extensions.registration.DynamicMap;
|
||||
import com.google.gerrit.extensions.registration.DynamicSet;
|
||||
import com.google.gerrit.reviewdb.client.Account;
|
||||
import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||
import com.google.gerrit.reviewdb.client.Branch;
|
||||
@@ -98,6 +99,27 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
|
||||
extends OperatorFactory<ChangeData, ChangeQueryBuilder> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a operand (operator value) passed to an operator into a
|
||||
* {@link Predicate}.
|
||||
*
|
||||
* Register a ChangeOperandFactory in a config Module like this (note, for
|
||||
* an example we are using the has predicate, when other predicate plugin
|
||||
* operands are created they can be registered in a similar manner):
|
||||
*
|
||||
* bind(ChangeHasOperandFactory.class)
|
||||
* .annotatedWith(Exports.named("your has operand"))
|
||||
* .to(YourClass.class);
|
||||
*
|
||||
*/
|
||||
private interface ChangeOperandFactory {
|
||||
Predicate<ChangeData> create(ChangeQueryBuilder builder)
|
||||
throws QueryParseException;
|
||||
}
|
||||
|
||||
public interface ChangeHasOperandFactory extends ChangeOperandFactory {
|
||||
}
|
||||
|
||||
private static final Pattern PAT_LEGACY_ID = Pattern.compile("^[1-9][0-9]*$");
|
||||
private static final Pattern PAT_CHANGE_ID = Pattern.compile(CHANGE_ID_PATTERN);
|
||||
private static final Pattern DEF_CHANGE = Pattern.compile(
|
||||
@@ -166,6 +188,7 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
|
||||
final Provider<InternalChangeQuery> queryProvider;
|
||||
final ChangeIndexRewriter rewriter;
|
||||
final DynamicMap<ChangeOperatorFactory> opFactories;
|
||||
final DynamicMap<ChangeHasOperandFactory> hasOperands;
|
||||
final IdentifiedUser.GenericFactory userFactory;
|
||||
final CapabilityControl.Factory capabilityControlFactory;
|
||||
final ChangeControl.GenericFactory changeControlGenericFactory;
|
||||
@@ -199,6 +222,7 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
|
||||
Provider<InternalChangeQuery> queryProvider,
|
||||
ChangeIndexRewriter rewriter,
|
||||
DynamicMap<ChangeOperatorFactory> opFactories,
|
||||
DynamicMap<ChangeHasOperandFactory> hasOperands,
|
||||
IdentifiedUser.GenericFactory userFactory,
|
||||
Provider<CurrentUser> self,
|
||||
CapabilityControl.Factory capabilityControlFactory,
|
||||
@@ -224,11 +248,9 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
|
||||
StarredChangesUtil starredChangesUtil,
|
||||
AccountCache accountCache,
|
||||
@GerritServerConfig Config cfg) {
|
||||
this(db, queryProvider, rewriter, opFactories, userFactory, self,
|
||||
capabilityControlFactory, changeControlGenericFactory, notesFactory,
|
||||
changeDataFactory, fillArgs, commentsUtil, accountResolver, groupBackend,
|
||||
allProjectsName, allUsersName, patchListCache, repoManager,
|
||||
projectCache, listChildProjects, submitDryRun, conflictsCache,
|
||||
this(db, queryProvider, rewriter, opFactories, hasOperands, userFactory,
|
||||
self, capabilityControlFactory, changeControlGenericFactory, notesFactory, changeDataFactory, fillArgs, commentsUtil,
|
||||
accountResolver, groupBackend, allProjectsName, allUsersName, patchListCache, repoManager, projectCache, listChildProjects, submitDryRun, conflictsCache,
|
||||
trackingFooters, indexes != null ? indexes.getSearchIndex() : null,
|
||||
indexConfig, listMembers, starredChangesUtil, accountCache,
|
||||
cfg == null ? true : cfg.getBoolean("change", "allowDrafts", true));
|
||||
@@ -239,6 +261,7 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
|
||||
Provider<InternalChangeQuery> queryProvider,
|
||||
ChangeIndexRewriter rewriter,
|
||||
DynamicMap<ChangeOperatorFactory> opFactories,
|
||||
DynamicMap<ChangeHasOperandFactory> hasOperands,
|
||||
IdentifiedUser.GenericFactory userFactory,
|
||||
Provider<CurrentUser> self,
|
||||
CapabilityControl.Factory capabilityControlFactory,
|
||||
@@ -293,15 +316,16 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
|
||||
this.starredChangesUtil = starredChangesUtil;
|
||||
this.accountCache = accountCache;
|
||||
this.allowsDrafts = allowsDrafts;
|
||||
this.hasOperands = hasOperands;
|
||||
}
|
||||
|
||||
Arguments asUser(CurrentUser otherUser) {
|
||||
return new Arguments(db, queryProvider, rewriter, opFactories, userFactory,
|
||||
Providers.of(otherUser),
|
||||
return new Arguments(db, queryProvider, rewriter, opFactories,
|
||||
hasOperands, userFactory, Providers.of(otherUser),
|
||||
capabilityControlFactory, changeControlGenericFactory, notesFactory,
|
||||
changeDataFactory, fillArgs, commentsUtil, accountResolver, groupBackend,
|
||||
allProjectsName, allUsersName, patchListCache, repoManager,
|
||||
projectCache, listChildProjects, submitDryRun,
|
||||
changeDataFactory, fillArgs, commentsUtil, accountResolver,
|
||||
groupBackend, allProjectsName, allUsersName, patchListCache,
|
||||
repoManager, projectCache, listChildProjects, submitDryRun,
|
||||
conflictsCache, trackingFooters, index, indexConfig, listMembers,
|
||||
starredChangesUtil, accountCache, allowsDrafts);
|
||||
}
|
||||
@@ -453,6 +477,16 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
|
||||
if ("edit".equalsIgnoreCase(value)) {
|
||||
return new EditByPredicate(self());
|
||||
}
|
||||
|
||||
// for plugins the value will be operandName_pluginName
|
||||
String[] names = value.split("_");
|
||||
if (names.length == 2) {
|
||||
ChangeHasOperandFactory op = args.hasOperands.get(names[1], names[0]);
|
||||
if (op != null) {
|
||||
return op.create(this);
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user