Skip to content

Commit

Permalink
fix for MID-3439 - added support for expression for substring filter.
Browse files Browse the repository at this point in the history
  • Loading branch information
katkav committed Jun 13, 2017
1 parent 33cf1e0 commit 4ba8d57
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 25 deletions.
Expand Up @@ -509,26 +509,20 @@ private static <C extends Containerable> RefFilter parseRefFilter(MapXNode claus

private static ExpressionWrapper parseExpression(MapXNode xmap, PrismContext prismContext) throws SchemaException {
Entry<QName, XNode> expressionEntry = xmap.getSingleEntryThatDoesNotMatch(
ELEMENT_VALUE, ELEMENT_MATCHING, ELEMENT_PATH);
ELEMENT_VALUE, ELEMENT_MATCHING, ELEMENT_ANCHOR_START, ELEMENT_ANCHOR_END, ELEMENT_PATH);
return PrismUtil.parseExpression(expressionEntry, prismContext);
}

private static <C extends Containerable> SubstringFilter parseSubstringFilter(MapXNode clauseXMap, PrismContainerDefinition<C> pcd, boolean preliminaryParsingOnly, PrismContext prismContext)
throws SchemaException {
ItemPath itemPath = getPath(clauseXMap);

if (itemPath == null || itemPath.isEmpty()){
throw new SchemaException("Could not convert query, because query does not contain item path.");
if (itemPath == null || itemPath.isEmpty()) {
throw new SchemaException("Could not convert query, because query does not contain item path.");
}
QName itemName = ItemPath.getName(itemPath.last());
QName matchingRule = getMatchingRule(clauseXMap);

XNode valueXnode = clauseXMap.get(ELEMENT_VALUE);

ItemDefinition itemDefinition = locateItemDefinition(valueXnode, itemPath, pcd, prismContext);

Item item = parseItem(new RootXNode(ELEMENT_VALUE, valueXnode), itemName, itemDefinition, prismContext);

Boolean anchorStart = clauseXMap.getParsedPrimitiveValue(ELEMENT_ANCHOR_START, DOMUtil.XSD_BOOLEAN);
if (anchorStart == null) {
anchorStart = false;
Expand All @@ -539,21 +533,46 @@ private static <C extends Containerable> SubstringFilter parseSubstringFilter(Ma
anchorEnd = false;
}

if (preliminaryParsingOnly) {
return null;
} else {
List values = item.getValues();
Object realValue;
if (values == null || values.isEmpty()) {
realValue = null; // TODO throw an exception?
} else if (values.size() > 1) {
throw new IllegalArgumentException("Expected at most 1 value, got " + values);
XNode valueXnode = clauseXMap.get(ELEMENT_VALUE);
ItemDefinition itemDefinition = locateItemDefinition(valueXnode, itemPath, pcd, prismContext);

if (valueXnode != null) {

Item item = parseItem(new RootXNode(ELEMENT_VALUE, valueXnode), itemName, itemDefinition, prismContext);

if (preliminaryParsingOnly) {
return null;
} else {
realValue = ((PrismPropertyValue) values.get(0)).getValue();
List values = item.getValues();
Object realValue;
if (values == null || values.isEmpty()) {
realValue = null; // TODO throw an exception?
} else if (values.size() > 1) {
throw new IllegalArgumentException("Expected at most 1 value, got " + values);
} else {
realValue = ((PrismPropertyValue) values.get(0)).getValue();
}
return SubstringFilter.createSubstring(itemPath, (PrismPropertyDefinition) itemDefinition, prismContext,
matchingRule, realValue, anchorStart, anchorEnd);

}
return SubstringFilter.createSubstring(itemPath, (PrismPropertyDefinition) itemDefinition,
prismContext, matchingRule, realValue, anchorStart, anchorEnd);
}
} else {
ExpressionWrapper expressionWrapper = parseExpression(clauseXMap, prismContext);
if (expressionWrapper != null) {
if (preliminaryParsingOnly) {
return null;
} else {
return SubstringFilter.createSubstring(itemPath, (PrismPropertyDefinition) itemDefinition, prismContext, matchingRule, expressionWrapper, anchorStart, anchorEnd);
}
} else {
if (preliminaryParsingOnly) {
return null;
} else {
return SubstringFilter.createSubstring(itemPath, (PrismPropertyDefinition) itemDefinition, prismContext, matchingRule,
(ExpressionWrapper) null, anchorStart, anchorEnd);
}
}
}
}

private static <C extends Containerable> OrgFilter parseOrgFilter(MapXNode clauseXMap, PrismContainerDefinition<C> pcd, boolean preliminaryParsingOnly, PrismContext prismContext) throws SchemaException {
Expand Down
Expand Up @@ -57,8 +57,12 @@ public static <T> SubstringFilter<T> createSubstring(@NotNull ItemPath path, @Nu
List<PrismPropertyValue<T>> values = anyValueToPropertyValueList(prismContext, anyValue);
return new SubstringFilter<>(path, itemDefinition, matchingRule, values, null, anchorStart, anchorEnd);
}

// TODO expression based substring filter

public static <T> SubstringFilter<T> createSubstring(@NotNull ItemPath path, @Nullable PrismPropertyDefinition<T> itemDefinition,
@NotNull PrismContext prismContext,
@Nullable QName matchingRule, ExpressionWrapper expressionWrapper, boolean anchorStart, boolean anchorEnd) {
return new SubstringFilter<>(path, itemDefinition, matchingRule, null, expressionWrapper, anchorStart, anchorEnd);
}

public boolean isAnchorStart() {
return anchorStart;
Expand Down
Expand Up @@ -400,7 +400,9 @@ public void testUserQuery() throws Exception {
File[] userQueriesToTest = new File[] { new File(TEST_DIR, "filter-user-by-fullName.xml"),
new File(TEST_DIR, "filter-user-by-name.xml"),
new File(TEST_DIR, "filter-user-substring-fullName.xml"),
new File(TEST_DIR, "filter-user-substring-employeeType.xml")
new File(TEST_DIR, "filter-user-substring-employeeType.xml"),
new File(TEST_DIR, "filter-user-substring-expression.xml"),
new File(TEST_DIR, "filter-user-substring-anchor-start-end-expression.xml")
};
// prismContext.silentMarshalObject(queryTypeNew, LOGGER);
for (File file : userQueriesToTest) {
Expand Down
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>

<!--
~ Copyright (c) 2010-2016 Evolveum
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<filter xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
xmlns="http://prism.evolveum.com/xml/ns/public/query-3">

<or xmlns="http://prism.evolveum.com/xml/ns/public/query-3">
<substring>
<path>c:employeeType</path>
<c:expression>
<c:script>
<c:code>
return "12345"
</c:code>
</c:script>
</c:expression>
<anchorStart>false</anchorStart>
<anchorEnd>false</anchorEnd>
</substring>
</or>
</filter>
@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>

<!--
~ Copyright (c) 2010-2016 Evolveum
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<filter xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
xmlns="http://prism.evolveum.com/xml/ns/public/query-3">

<or xmlns="http://prism.evolveum.com/xml/ns/public/query-3">
<substring>
<path>c:employeeType</path>
<c:expression>
<c:script>
<c:code>
return "12345"
</c:code>
</c:script>
</c:expression>
</substring>
</or>
</filter>

0 comments on commit 4ba8d57

Please sign in to comment.