Skip to content

Commit

Permalink
AssignmentPanel: Added normalization to exists filter for targetRef/@…
Browse files Browse the repository at this point in the history
… search items
  • Loading branch information
tonydamage committed Sep 28, 2022
1 parent 362eb63 commit ced2c2c
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -479,5 +479,9 @@ public void setContainerDefinition(PrismContainerDefinition<C> typeDefinitionFor
containerDefinitionOverride = typeDefinitionForSearch;
}

public PrismContainerDefinition<C> getContainerDefinitionOverride() {
return containerDefinitionOverride;
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,26 @@
import com.evolveum.midpoint.prism.PrismConstants;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.prism.query.AndFilter;
import com.evolveum.midpoint.prism.query.FullTextFilter;
import com.evolveum.midpoint.prism.query.ObjectFilter;
import com.evolveum.midpoint.prism.query.ObjectOrdering;
import com.evolveum.midpoint.prism.query.ObjectQuery;
import com.evolveum.midpoint.prism.query.OrderDirection;
import com.evolveum.midpoint.prism.query.ValueFilter;
import com.evolveum.midpoint.schema.SchemaConstantsGenerated;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.schema.util.ObjectQueryUtil;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.web.component.prism.ValueStatus;
import com.evolveum.midpoint.gui.impl.component.search.Search;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentHolderType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType;

import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.SearchBoxModeType;

import org.apache.wicket.Component;
import org.apache.wicket.extensions.markup.html.repeater.util.SortParam;
Expand All @@ -48,6 +53,8 @@ public class RepoAssignmentListProvider extends ContainerListDataProvider<Assign

public static final String TARGET_NAME_STRING = "targetRef.targetName.orig";
private static final ItemPath TARGET_NAME_PATH = ItemPath.create(AssignmentType.F_TARGET_REF, PrismConstants.T_OBJECT_REFERENCE, ObjectType.F_NAME);
private static final ItemPath TARGET_REF_OBJ = ItemPath.create(AssignmentType.F_TARGET_REF, PrismConstants.T_OBJECT_REFERENCE);



private final IModel<List<PrismContainerValueWrapper<AssignmentType>>> model;
Expand Down Expand Up @@ -211,17 +218,9 @@ protected void postProcessWrapper(PrismContainerValueWrapper<AssignmentType> val
*/
@Override
public ObjectQuery getQuery() {
var search = getSearchModel();
var orig = search.getObject() == null ? null : search.getObject().createObjectQuery(getVariables(), getPageBase(), null);

if (orig != null && orig.getFilter() instanceof FullTextFilter) {
// User entered full text filter, lets make sure it is invoked on targetRef
orig = getPrismContext().queryFor(getType()).exists(AssignmentType.F_TARGET_REF, PrismConstants.T_OBJECT_REFERENCE)
.filter(orig.getFilter())
.build();
}

orig = mergeQueries(orig, getCustomizeContentQuery());
var customizeQuery = getCustomizeContentQuery();
var orig = normalizedSearchQuery();
orig = mergeQueries(orig, customizeQuery);
var idFilter = postFilterIds();
ObjectFilter filter = orig != null ? orig.getFilter() : null;
if (orig != null) {
Expand Down Expand Up @@ -252,6 +251,77 @@ public ObjectQuery getQuery() {
.build();
}

private QName determineTargetRefType() {
var searchOverride = getSearchModel().getObject().getContainerDefinitionOverride();
if (searchOverride == null) {
return null;
}
var targetRefDef = searchOverride.findReferenceDefinition(AssignmentType.F_TARGET_REF);
QName targetType = targetRefDef.getTargetTypeName();
if (targetType != null && !Objects.equals(AssignmentHolderType.COMPLEX_TYPE, targetType)) {
// target type was overriden
return targetType;
}


return null;
}

private ObjectQuery normalizedSearchQuery() {
var search = getSearchModel();
var orig = search.getObject() == null ? null : search.getObject().createObjectQuery(getVariables(), getPageBase(), null);

var targetType = determineTargetRefType();

if (orig != null && targetType != null && SearchBoxModeType.BASIC.equals(search.getObject().getSearchMode()) ) {
// We should optimize extract all dereferenced items from filter to form single exists(and) filter
// which can be later extended to exists(type(and))) in order to provide
// best information for repository

// This code is written with assumption that all target filters have path targetRef/@
var root = ObjectQueryUtil.simplify(orig.getFilter());
List<ObjectFilter> filters;
if (root instanceof AndFilter) {
filters = new ArrayList<>(((AndFilter) root).getConditions());
} else {
filters = new ArrayList<>();
filters.add(root);
}
var iter = filters.iterator();
ArrayList<ObjectFilter> targetObjFilters = new ArrayList<>();
while (iter.hasNext()) {
var filter = iter.next();
if (filter instanceof ValueFilter<?, ?>) {
if (((ValueFilter<?,?>) filter).canNestInsideExists(TARGET_REF_OBJ)) {
// Filter matches targetRef/@/
iter.remove();
targetObjFilters.add(((ValueFilter<?,?>) filter).nested(TARGET_REF_OBJ));
}
}
}
if (!targetObjFilters.isEmpty()) {
// We create replacement only if targetObjFilters were successfully created
var typeAnd =getPrismContext().queryFactory().createAnd(targetObjFilters);
orig = getPrismContext().queryFor(getType()).exists(TARGET_REF_OBJ)
.block()
.type(targetType).filter(typeAnd)
.endBlock().build();
orig.addFilter(getPrismContext().queryFactory().createAndOptimized(filters));
}

}



if (orig != null && orig.getFilter() instanceof FullTextFilter) {
// User entered full text filter, lets make sure it is invoked on targetRef
orig = getPrismContext().queryFor(getType()).exists(TARGET_REF_OBJ)
.filter(orig.getFilter())
.build();
}
return orig;
}

private ObjectQuery mergeQueries(ObjectQuery origQuery, ObjectQuery query) {
if (query != null) {
if (origQuery == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,12 @@ public static ObjectFilter simplify(ObjectFilter filter, PrismContext prismConte
// AND with "true", just skip it
} else {
ObjectFilter simplifiedSubfilter = simplify(subfilter, prismContext);
if (simplifiedSubfilter instanceof NoneFilter) {
if (simplifiedSubfilter instanceof AndFilter) {
// Unwrap AND filter to parent and
for (ObjectFilter condition : ((AndFilter) simplifiedSubfilter).getConditions()) {
simplifiedFilter.addCondition(condition);
}
} else if (simplifiedSubfilter instanceof NoneFilter) {
return FilterCreationUtil.createNone(prismContext);
} else if (simplifiedSubfilter == null || simplifiedSubfilter instanceof AllFilter) {
// skip
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public <ID extends ItemDefinition<?>> ID findItemDefinition(@NotNull ItemPath pa
if (rest.isEmpty()) {
return clazz.cast(firstChild);
}
return (ID) firstChild.findItemDefinition(path, clazz);
return (ID) firstChild.findItemDefinition(rest, clazz);

}

Expand Down

0 comments on commit ced2c2c

Please sign in to comment.