Skip to content

Commit

Permalink
Allow multiple filters in search expressions
Browse files Browse the repository at this point in the history
In order to allow smooth migration from OID-based association
or assignment target search evaluation expressions to filter-based
ones, we now allow multiple "filter" elements in such configuration.
Each OID will be converted to a single filter.

Other changes:

1. The default object resolver is now model-based, for asserters
that are initialized in AbstractModelIntegrationTest.

2. Convenience "assertSuccess()" method for tests with implicit
operation result.

Note that GUI was adapted only roughly, to make compiler happy.
It needs more attention.
  • Loading branch information
mederly committed Mar 11, 2024
1 parent 67acb57 commit 554eb0f
Show file tree
Hide file tree
Showing 17 changed files with 361 additions and 271 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ public static JAXBElement<?> createAssociationTargetSearchElement(PrismContext p

SearchFilterType filterType = new SearchFilterType();
filterType.setFilterClauseXNode(filterClauseNode);
searchObjectExpressionEvaluatorType.setFilter(filterType);
searchObjectExpressionEvaluatorType.getFilter().add(filterType);

evaluator.setValue(searchObjectExpressionEvaluatorType);
return evaluator;
Expand All @@ -403,11 +403,11 @@ public static MapXNode getOrCreateAssociationTargetSearchValues(ExpressionType e
if (evaluator == null) {
evaluator = new SearchObjectExpressionEvaluatorType();
}
SearchFilterType filterType = evaluator.getFilter();
if (filterType == null) {
filterType = new SearchFilterType();
List<SearchFilterType> filterTypeList = evaluator.getFilter();
if (filterTypeList.isEmpty()) {
filterTypeList.add(new SearchFilterType());
}
MapXNode filterClauseNode = filterType.getFilterClauseXNode();
MapXNode filterClauseNode = filterTypeList.get(0).getFilterClauseXNode(); // TODO is this correct?
if (filterClauseNode == null) {
filterClauseNode = prismContext.xnodeFactory().map();
}
Expand All @@ -430,7 +430,8 @@ public static void updateAssociationTargetSearchValue(ExpressionType expression,
EqualFilter<?> pathFilter = prismContext.queryFactory().createEqual(ItemPath.create(newPath), null, null, prismContext, newValue);

SearchFilterType filterType = prismContext.getQueryConverter().createSearchFilterType(pathFilter);
associationTargetSearchType.setFilter(filterType);
associationTargetSearchType.getFilter().clear(); // TODO is this correct?
associationTargetSearchType.getFilter().add(filterType);
JAXBElement<SearchObjectExpressionEvaluatorType> evaluator = new ObjectFactory().createAssociationTargetSearch(associationTargetSearchType);

removeEvaluatorByName(expression, SchemaConstantsGenerated.C_ASSOCIATION_TARGET_SEARCH);
Expand Down Expand Up @@ -636,11 +637,11 @@ public static MapXNode getAssociationTargetSearchFilterValuesMap(ExpressionType
}
JAXBElement element = ExpressionUtil.findFirstEvaluatorByName(expression, SchemaConstantsGenerated.C_ASSOCIATION_TARGET_SEARCH);
if (element != null && element.getValue() != null && element.getValue() instanceof SearchObjectExpressionEvaluatorType) {
SearchFilterType filter = ((SearchObjectExpressionEvaluatorType) element.getValue()).getFilter();
if (filter == null) {
List<SearchFilterType> filters = ((SearchObjectExpressionEvaluatorType) element.getValue()).getFilter();
if (filters.isEmpty()) {
return null;
}
MapXNode filterValue = filter.getFilterClauseXNode();
MapXNode filterValue = filters.get(0).getFilterClauseXNode(); // TODO is this correct?
return filterValue != null && filterValue.containsKey(new QName(SchemaConstantsGenerated.NS_QUERY, "equal")) ?
(MapXNode) filterValue.get(new QName(SchemaConstantsGenerated.NS_QUERY, "equal")) : null;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,10 +139,9 @@ private static LocalizableMessage toStringValue(Object value) {
if (evaluator.getValue() instanceof RawType) {
expressionString.append(PrettyPrinter.prettyPrint(evaluator.getValue()));
expressionString.append("; ");
} else if (evaluator.getValue() instanceof SearchObjectExpressionEvaluatorType) {
SearchObjectExpressionEvaluatorType evaluatorValue = (SearchObjectExpressionEvaluatorType) evaluator.getValue();
if (evaluatorValue.getFilter() != null) {
DebugUtil.debugDumpMapMultiLine(expressionString, evaluatorValue.getFilter().getFilterClauseXNode().toMap(),
} else if (evaluator.getValue() instanceof SearchObjectExpressionEvaluatorType searchEvaluatorValue) {
for (var filter : searchEvaluatorValue.getFilter()) {
DebugUtil.debugDumpMapMultiLine(expressionString, filter.getFilterClauseXNode().toMap(),
0, false, null);

//TODO temporary hack: removing namespace part of the QName
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6615,13 +6615,26 @@

It is planned to be used to "remember" the search result. E.g. to
search for the target on import and then store the fixed OID.
But this is not yet implemented.
But this is not yet implemented. Actually, it can be a problem if multiple objects
are found by the search by filter.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="filter" type="q:SearchFilterType" minOccurs="0">
<xsd:element name="filter" type="q:SearchFilterType" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation>
Filter or filters to use to look for objects.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="searchStrategy" type="tns:ObjectSearchStrategyType" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
How we try to find matching objects. Note that when "onResourceIfNeeded" is used,
it is applied onto the filters individually. That means, that each filter is evaluated
against the repository, and if nothing is found, the resource is consulted.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="defaultTargetRef" type="tns:ObjectReferenceType" minOccurs="0">
<xsd:annotation>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public void testAccessObjectTemplateMultithreaded() throws Exception {
for (int i = 0; i < THREADS; i++) {
Thread thread = new Thread(() -> {
try {
ObjectFilter filter = prismContext.getQueryConverter().createObjectFilter(RoleType.class, evaluator.getFilter());
ObjectFilter filter = prismContext.getQueryConverter().createObjectFilter(RoleType.class, evaluator.getFilter().get(0));
EqualFilter equalFilter = (EqualFilter) filter;
assertNotNull(equalFilter.getExpression());
ExpressionType expression = (ExpressionType) equalFilter.getExpression().getExpression();
Expand Down

0 comments on commit 554eb0f

Please sign in to comment.