Merge "Allow plugins to define 'has' search operands."
This commit is contained in:
commit
56c3634d05
@ -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]]
|
||||||
== Simple Configuration in `gerrit.config`
|
== Simple Configuration in `gerrit.config`
|
||||||
|
|
||||||
|
@ -376,6 +376,7 @@ public class GerritGlobalModule extends FactoryModule {
|
|||||||
DynamicSet.setOf(binder(), UploadValidationListener.class);
|
DynamicSet.setOf(binder(), UploadValidationListener.class);
|
||||||
|
|
||||||
DynamicMap.mapOf(binder(), ChangeQueryBuilder.ChangeOperatorFactory.class);
|
DynamicMap.mapOf(binder(), ChangeQueryBuilder.ChangeOperatorFactory.class);
|
||||||
|
DynamicMap.mapOf(binder(), ChangeQueryBuilder.ChangeHasOperandFactory.class);
|
||||||
install(new GitwebConfig.LegacyModule(cfg));
|
install(new GitwebConfig.LegacyModule(cfg));
|
||||||
|
|
||||||
bind(AnonymousUser.class);
|
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.data.SubmitRecord;
|
||||||
import com.google.gerrit.common.errors.NotSignedInException;
|
import com.google.gerrit.common.errors.NotSignedInException;
|
||||||
import com.google.gerrit.extensions.registration.DynamicMap;
|
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.Account;
|
||||||
import com.google.gerrit.reviewdb.client.AccountGroup;
|
import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||||
import com.google.gerrit.reviewdb.client.Branch;
|
import com.google.gerrit.reviewdb.client.Branch;
|
||||||
@ -98,6 +99,27 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
|
|||||||
extends OperatorFactory<ChangeData, ChangeQueryBuilder> {
|
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_LEGACY_ID = Pattern.compile("^[1-9][0-9]*$");
|
||||||
private static final Pattern PAT_CHANGE_ID = Pattern.compile(CHANGE_ID_PATTERN);
|
private static final Pattern PAT_CHANGE_ID = Pattern.compile(CHANGE_ID_PATTERN);
|
||||||
private static final Pattern DEF_CHANGE = Pattern.compile(
|
private static final Pattern DEF_CHANGE = Pattern.compile(
|
||||||
@ -166,6 +188,7 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
|
|||||||
final Provider<InternalChangeQuery> queryProvider;
|
final Provider<InternalChangeQuery> queryProvider;
|
||||||
final ChangeIndexRewriter rewriter;
|
final ChangeIndexRewriter rewriter;
|
||||||
final DynamicMap<ChangeOperatorFactory> opFactories;
|
final DynamicMap<ChangeOperatorFactory> opFactories;
|
||||||
|
final DynamicMap<ChangeHasOperandFactory> hasOperands;
|
||||||
final IdentifiedUser.GenericFactory userFactory;
|
final IdentifiedUser.GenericFactory userFactory;
|
||||||
final CapabilityControl.Factory capabilityControlFactory;
|
final CapabilityControl.Factory capabilityControlFactory;
|
||||||
final ChangeControl.GenericFactory changeControlGenericFactory;
|
final ChangeControl.GenericFactory changeControlGenericFactory;
|
||||||
@ -199,6 +222,7 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
|
|||||||
Provider<InternalChangeQuery> queryProvider,
|
Provider<InternalChangeQuery> queryProvider,
|
||||||
ChangeIndexRewriter rewriter,
|
ChangeIndexRewriter rewriter,
|
||||||
DynamicMap<ChangeOperatorFactory> opFactories,
|
DynamicMap<ChangeOperatorFactory> opFactories,
|
||||||
|
DynamicMap<ChangeHasOperandFactory> hasOperands,
|
||||||
IdentifiedUser.GenericFactory userFactory,
|
IdentifiedUser.GenericFactory userFactory,
|
||||||
Provider<CurrentUser> self,
|
Provider<CurrentUser> self,
|
||||||
CapabilityControl.Factory capabilityControlFactory,
|
CapabilityControl.Factory capabilityControlFactory,
|
||||||
@ -224,11 +248,9 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
|
|||||||
StarredChangesUtil starredChangesUtil,
|
StarredChangesUtil starredChangesUtil,
|
||||||
AccountCache accountCache,
|
AccountCache accountCache,
|
||||||
@GerritServerConfig Config cfg) {
|
@GerritServerConfig Config cfg) {
|
||||||
this(db, queryProvider, rewriter, opFactories, userFactory, self,
|
this(db, queryProvider, rewriter, opFactories, hasOperands, userFactory,
|
||||||
capabilityControlFactory, changeControlGenericFactory, notesFactory,
|
self, capabilityControlFactory, changeControlGenericFactory, notesFactory, changeDataFactory, fillArgs, commentsUtil,
|
||||||
changeDataFactory, fillArgs, commentsUtil, accountResolver, groupBackend,
|
accountResolver, groupBackend, allProjectsName, allUsersName, patchListCache, repoManager, projectCache, listChildProjects, submitDryRun, conflictsCache,
|
||||||
allProjectsName, allUsersName, patchListCache, repoManager,
|
|
||||||
projectCache, listChildProjects, submitDryRun, conflictsCache,
|
|
||||||
trackingFooters, indexes != null ? indexes.getSearchIndex() : null,
|
trackingFooters, indexes != null ? indexes.getSearchIndex() : null,
|
||||||
indexConfig, listMembers, starredChangesUtil, accountCache,
|
indexConfig, listMembers, starredChangesUtil, accountCache,
|
||||||
cfg == null ? true : cfg.getBoolean("change", "allowDrafts", true));
|
cfg == null ? true : cfg.getBoolean("change", "allowDrafts", true));
|
||||||
@ -239,6 +261,7 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
|
|||||||
Provider<InternalChangeQuery> queryProvider,
|
Provider<InternalChangeQuery> queryProvider,
|
||||||
ChangeIndexRewriter rewriter,
|
ChangeIndexRewriter rewriter,
|
||||||
DynamicMap<ChangeOperatorFactory> opFactories,
|
DynamicMap<ChangeOperatorFactory> opFactories,
|
||||||
|
DynamicMap<ChangeHasOperandFactory> hasOperands,
|
||||||
IdentifiedUser.GenericFactory userFactory,
|
IdentifiedUser.GenericFactory userFactory,
|
||||||
Provider<CurrentUser> self,
|
Provider<CurrentUser> self,
|
||||||
CapabilityControl.Factory capabilityControlFactory,
|
CapabilityControl.Factory capabilityControlFactory,
|
||||||
@ -293,15 +316,16 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
|
|||||||
this.starredChangesUtil = starredChangesUtil;
|
this.starredChangesUtil = starredChangesUtil;
|
||||||
this.accountCache = accountCache;
|
this.accountCache = accountCache;
|
||||||
this.allowsDrafts = allowsDrafts;
|
this.allowsDrafts = allowsDrafts;
|
||||||
|
this.hasOperands = hasOperands;
|
||||||
}
|
}
|
||||||
|
|
||||||
Arguments asUser(CurrentUser otherUser) {
|
Arguments asUser(CurrentUser otherUser) {
|
||||||
return new Arguments(db, queryProvider, rewriter, opFactories, userFactory,
|
return new Arguments(db, queryProvider, rewriter, opFactories,
|
||||||
Providers.of(otherUser),
|
hasOperands, userFactory, Providers.of(otherUser),
|
||||||
capabilityControlFactory, changeControlGenericFactory, notesFactory,
|
capabilityControlFactory, changeControlGenericFactory, notesFactory,
|
||||||
changeDataFactory, fillArgs, commentsUtil, accountResolver, groupBackend,
|
changeDataFactory, fillArgs, commentsUtil, accountResolver,
|
||||||
allProjectsName, allUsersName, patchListCache, repoManager,
|
groupBackend, allProjectsName, allUsersName, patchListCache,
|
||||||
projectCache, listChildProjects, submitDryRun,
|
repoManager, projectCache, listChildProjects, submitDryRun,
|
||||||
conflictsCache, trackingFooters, index, indexConfig, listMembers,
|
conflictsCache, trackingFooters, index, indexConfig, listMembers,
|
||||||
starredChangesUtil, accountCache, allowsDrafts);
|
starredChangesUtil, accountCache, allowsDrafts);
|
||||||
}
|
}
|
||||||
@ -453,6 +477,16 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
|
|||||||
if ("edit".equalsIgnoreCase(value)) {
|
if ("edit".equalsIgnoreCase(value)) {
|
||||||
return new EditByPredicate(self());
|
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();
|
throw new IllegalArgumentException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user