From af694214af85492eb331508945f52e5fb119bb35 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Tue, 3 May 2016 19:18:37 +0200 Subject: [PATCH] Cleanup of query serialization (MID-2771) - first step. Added GT/GE/LT/LE filters. --- build-system/pom.xml | 11 + .../prism/PrismContainerDefinition.java | 10 +- .../midpoint/prism/parser/QueryConvertor.java | 736 +++++++++--------- .../midpoint/prism/parser/XPathHolder.java | 47 +- .../prism/path/IdentifierPathSegment.java | 11 +- .../midpoint/prism/path/ItemPath.java | 38 +- .../path/ObjectReferencePathSegment.java | 11 +- .../prism/path/ParentPathSegment.java | 11 +- .../midpoint/prism/query/AllFilter.java | 9 + .../midpoint/prism/query/AndFilter.java | 4 + .../prism/query/ComparativeFilter.java | 32 +- .../midpoint/prism/query/EqualFilter.java | 17 +- .../midpoint/prism/query/ExistsFilter.java | 49 +- .../midpoint/prism/query/GreaterFilter.java | 38 +- .../midpoint/prism/query/InFilter.java | 5 + .../midpoint/prism/query/InOidFilter.java | 50 +- .../midpoint/prism/query/LessFilter.java | 50 +- .../midpoint/prism/query/LogicalFilter.java | 18 +- .../midpoint/prism/query/NoneFilter.java | 11 + .../midpoint/prism/query/NotFilter.java | 6 + .../midpoint/prism/query/ObjectFilter.java | 2 + .../midpoint/prism/query/ObjectOrdering.java | 26 + .../midpoint/prism/query/ObjectPaging.java | 44 ++ .../midpoint/prism/query/ObjectQuery.java | 35 + .../midpoint/prism/query/OrFilter.java | 6 + .../midpoint/prism/query/OrgFilter.java | 4 +- .../prism/query/PropertyValueFilter.java | 133 ++-- .../prism/query/QueryJaxbConvertor.java | 18 +- .../midpoint/prism/query/RefFilter.java | 6 + .../midpoint/prism/query/SubstringFilter.java | 35 +- .../midpoint/prism/query/TypeFilter.java | 3 +- .../midpoint/prism/query/UndefinedFilter.java | 11 + .../midpoint/prism/query/ValueFilter.java | 14 +- .../prism/query/builder/R_AtomicFilter.java | 33 +- .../prism/query/builder/S_ConditionEntry.java | 11 +- .../midpoint/prism/schema/SchemaRegistry.java | 43 +- .../midpoint/prism/util/PrismTestUtil.java | 10 + .../_public/types_3/ObjectReferenceType.java | 36 +- .../main/resources/xml/ns/public/query-3.xsd | 268 ++++--- .../main/resources/xml/ns/public/types-3.xsd | 12 + .../evolveum/midpoint/prism/TestDelta.java | 1 - infra/schema/pom.xml | 15 + .../midpoint/schema/TestQueryConvertor.java | 393 +++++++--- .../midpoint/schema/test/XPathTest.java | 17 + .../queryconvertor/filter-account.xml | 4 +- .../resources/queryconvertor/test100All.xml | 22 + .../resources/queryconvertor/test110None.xml | 22 + .../queryconvertor/test120Undefined.xml | 22 + .../resources/queryconvertor/test200Equal.xml | 26 + .../queryconvertor/test210EqualMultiple.xml | 26 + .../test220EqualRightHandItem.xml | 25 + .../queryconvertor/test300Greater.xml | 25 + .../queryconvertor/test310AllComparisons.xml | 43 + .../queryconvertor/test350Substring.xml | 43 + .../resources/queryconvertor/test360Ref.xml | 44 ++ .../queryconvertor/test365RefTwoWay.xml | 38 + .../queryconvertor/test400OrgFilterRoot.xml | 24 + .../test410OrgFilterSubtree.xml | 11 + .../queryconvertor/test420OrgFilterDirect.xml | 27 + .../test430OrgFilterDefaultScope.xml | 27 + .../resources/queryconvertor/test500InOid.xml | 26 + .../queryconvertor/test510InOidContainer.xml | 32 + .../queryconvertor/test590Logicals.xml | 35 + .../resources/queryconvertor/test600Type.xml | 30 + .../queryconvertor/test700Exists.xml | 44 ++ .../impl/AccCertQueryHelper.java | 7 +- .../midpoint/repo/sql/CertificationTest.java | 7 +- .../repo/sql/QueryInterpreter2Test.java | 11 +- .../repo/sql/ObjectPagingAfterOid.java | 21 + .../restriction/AnyPropertyRestriction.java | 2 +- .../restriction/PropertyRestriction.java | 6 +- .../testing/model/client/sample/Main.java | 2 +- 72 files changed, 2097 insertions(+), 895 deletions(-) create mode 100644 infra/schema/src/test/resources/queryconvertor/test100All.xml create mode 100644 infra/schema/src/test/resources/queryconvertor/test110None.xml create mode 100644 infra/schema/src/test/resources/queryconvertor/test120Undefined.xml create mode 100644 infra/schema/src/test/resources/queryconvertor/test200Equal.xml create mode 100644 infra/schema/src/test/resources/queryconvertor/test210EqualMultiple.xml create mode 100644 infra/schema/src/test/resources/queryconvertor/test220EqualRightHandItem.xml create mode 100644 infra/schema/src/test/resources/queryconvertor/test300Greater.xml create mode 100644 infra/schema/src/test/resources/queryconvertor/test310AllComparisons.xml create mode 100644 infra/schema/src/test/resources/queryconvertor/test350Substring.xml create mode 100644 infra/schema/src/test/resources/queryconvertor/test360Ref.xml create mode 100644 infra/schema/src/test/resources/queryconvertor/test365RefTwoWay.xml create mode 100644 infra/schema/src/test/resources/queryconvertor/test400OrgFilterRoot.xml create mode 100644 infra/schema/src/test/resources/queryconvertor/test410OrgFilterSubtree.xml create mode 100644 infra/schema/src/test/resources/queryconvertor/test420OrgFilterDirect.xml create mode 100644 infra/schema/src/test/resources/queryconvertor/test430OrgFilterDefaultScope.xml create mode 100644 infra/schema/src/test/resources/queryconvertor/test500InOid.xml create mode 100644 infra/schema/src/test/resources/queryconvertor/test510InOidContainer.xml create mode 100644 infra/schema/src/test/resources/queryconvertor/test590Logicals.xml create mode 100644 infra/schema/src/test/resources/queryconvertor/test600Type.xml create mode 100644 infra/schema/src/test/resources/queryconvertor/test700Exists.xml diff --git a/build-system/pom.xml b/build-system/pom.xml index 1c18085db8d..78a61d93341 100644 --- a/build-system/pom.xml +++ b/build-system/pom.xml @@ -67,6 +67,7 @@ 4.0.4.RELEASE 6.8.8 1.2 + 2.1.1 2.2.3 4.3.8.Final 1.3.171 @@ -753,6 +754,16 @@ testng ${testng.version} + + org.xmlunit + xmlunit-core + ${xmlunit.version} + + + org.xmlunit + xmlunit-legacy + ${xmlunit.version} + xml-resolver xml-resolver diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContainerDefinition.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContainerDefinition.java index 308a5c23560..42cae34c972 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContainerDefinition.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContainerDefinition.java @@ -227,8 +227,14 @@ public ID findItemDefinition(ItemPath path, Class ObjectQuery parseQuery(MapXNode xmap, Class clazz, PrismContext prismContext) - throws SchemaException { + // please keep the order of filter clause symbols synchronized with query-3.xsd - if (xmap == null){ - return null; - } - - PrismObjectDefinition objDef = prismContext.getSchemaRegistry().findObjectDefinitionByCompileTimeClass(clazz); + private static final QName CLAUSE_ALL = new QName(NS_QUERY, "all"); + private static final QName CLAUSE_NONE = new QName(NS_QUERY, "none"); + private static final QName CLAUSE_UNDEFINED = new QName(NS_QUERY, "undefined"); - if (objDef == null) { - throw new SchemaException("Cannot find obj definition for "+clazz); - } + private static final QName CLAUSE_EQUAL = new QName(NS_QUERY, "equal"); + private static final QName CLAUSE_GREATER = new QName(NS_QUERY, "greater"); + private static final QName CLAUSE_GREATER_OR_EQUAL = new QName(NS_QUERY, "greaterOrEqual"); + private static final QName CLAUSE_LESS = new QName(NS_QUERY, "less"); + private static final QName CLAUSE_LESS_OR_EQUAL = new QName(NS_QUERY, "lessOrEqual"); + private static final QName CLAUSE_SUBSTRING = new QName(NS_QUERY, "substring"); - return parseQuery(xmap, objDef); - } - - public static ObjectQuery parseQuery(MapXNode xmap, PrismObjectDefinition objDef) throws SchemaException { - if (xmap == null){ - return null; - } - - XNode xnodeFilter = xmap.get(KEY_FILTER); - if (xnodeFilter != null) { - throw new SchemaException("No filter in query"); - } - if (!(xnodeFilter instanceof MapXNode)) { - throw new SchemaException("Cannot parse filter from "+xnodeFilter); - } - ObjectFilter filter = parseFilter((MapXNode)xnodeFilter, objDef); - - ObjectQuery query = new ObjectQuery(); - query.setFilter(filter); - - XNode xnodePaging = xmap.get(KEY_PAGING); - if (xnodePaging != null) { - throw new UnsupportedOperationException("work in progress"); -// ObjectPaging paging = PagingConvertor.parsePaging(xnodePaging); -// query.setPaging(paging); - } + private static final QName CLAUSE_REF = new QName(NS_QUERY, "ref"); + private static final QName CLAUSE_ORG = new QName(NS_QUERY, "org"); + private static final QName CLAUSE_IN_OID = new QName(NS_QUERY, "inOid"); + + private static final QName CLAUSE_AND = new QName(NS_QUERY, "and"); + private static final QName CLAUSE_OR = new QName(NS_QUERY, "or"); + private static final QName CLAUSE_NOT = new QName(NS_QUERY, "not"); + + private static final QName CLAUSE_TYPE = new QName(NS_QUERY, "type"); + private static final QName CLAUSE_EXISTS = new QName(NS_QUERY, "exists"); + + // common elements + private static final QName ELEMENT_PATH = new QName(NS_QUERY, "path"); + private static final QName ELEMENT_MATCHING = new QName(NS_QUERY, "matching"); + private static final QName ELEMENT_VALUE = new QName(NS_QUERY, "value"); + private static final QName ELEMENT_RIGHT_HAND_SIDE_PATH = new QName(NS_QUERY, "rightHandSidePath"); + + // substring + private static final QName ELEMENT_ANCHOR_START = new QName(NS_QUERY, "anchorStart"); + private static final QName ELEMENT_ANCHOR_END = new QName(NS_QUERY, "anchorEnd"); + + // org + private static final QName ELEMENT_ORG_REF = new QName(NS_QUERY, "orgRef"); + private static final QName ELEMENT_SCOPE = new QName(NS_QUERY, "scope"); + private static final QName ELEMENT_IS_ROOT = new QName(NS_QUERY, "isRoot"); + + // inOid + private static final QName ELEMENT_OID = new QName(NS_QUERY, "oid"); + private static final QName ELEMENT_CONSIDER_OWNER = new QName(NS_QUERY, "considerOwner"); + + // type and exists + public static final QName ELEMENT_TYPE = new QName(NS_QUERY, "type"); + private static final QName ELEMENT_FILTER = new QName(NS_QUERY, "filter"); - return query; - } - /** * Used by XNodeProcessor and similar code that does not have complete schema for the filter */ public static ObjectFilter parseFilter(XNode xnode, PrismContext prismContext) throws SchemaException { Validate.notNull(prismContext); MapXNode xmap = toMap(xnode); - return parseFilterContainer(xmap, null, false, prismContext); + return parseFilterInternal(xmap, null, false, prismContext); } - public static ObjectFilter parseFilter(MapXNode xmap, PrismObjectDefinition objDef) throws SchemaException { + public static ObjectFilter parseFilter(MapXNode xmap, PrismContainerDefinition objDef) throws SchemaException { Validate.notNull(objDef); if (xmap == null) { return null; } - return parseFilterContainer(xmap, objDef, false, objDef.getPrismContext()); + return parseFilterInternal(xmap, objDef, false, objDef.getPrismContext()); } public static ObjectFilter parseFilter(SearchFilterType filter, Class clazz, PrismContext prismContext) throws SchemaException { @@ -174,67 +138,75 @@ public static ObjectFilter parseFilter(SearchFilterType filter, PrismObjectDefin return parseFilter(filter.getFilterClauseXNode(), objDef); } - // beware, pcd may be null - private static ObjectFilter parseFilterContainer(MapXNode xmap, PrismContainerDefinition pcd, - boolean preliminaryParsingOnly, PrismContext prismContext) throws SchemaException { + private static ObjectFilter parseFilterInternal( + @NotNull MapXNode filterXMap, + @Nullable PrismContainerDefinition pcd, + boolean preliminaryParsingOnly, + @NotNull PrismContext prismContext) throws SchemaException { + Validate.notNull(prismContext); - Entry entry = xmap.getSingleEntryThatDoesNotMatch(SearchFilterType.F_DESCRIPTION); - QName filterQName = entry.getKey(); - XNode xsubnode = entry.getValue(); - return parseFilterContainer(xsubnode, filterQName, pcd, preliminaryParsingOnly, prismContext); + Entry clauseEntry = filterXMap.getSingleEntryThatDoesNotMatch(SearchFilterType.F_DESCRIPTION); + QName clauseQName = clauseEntry.getKey(); + XNode clauseContent = clauseEntry.getValue(); + return parseFilterInternal(clauseContent, clauseQName, pcd, preliminaryParsingOnly, prismContext); } - private static ObjectFilter parseFilterContainer(XNode xsubnode, QName filterQName, + private static ObjectFilter parseFilterInternal(XNode clauseContent, QName clauseQName, PrismContainerDefinition pcd, boolean preliminaryParsingOnly, PrismContext prismContext) throws SchemaException { - - if (QNameUtil.match(filterQName, KEY_FILTER_AND)) { - return parseAndFilter(xsubnode, pcd, preliminaryParsingOnly, prismContext); - } - - if (QNameUtil.match(filterQName, KEY_FILTER_OR)) { - return parseOrFilter(xsubnode, pcd, preliminaryParsingOnly, prismContext); - } - - if (QNameUtil.match(filterQName, KEY_FILTER_NOT)) { - return parseNotFilter(xsubnode, pcd, preliminaryParsingOnly, prismContext); - } - - if (QNameUtil.match(filterQName, KEY_FILTER_EQUAL)) { - return parseEqualFilter(xsubnode, pcd, preliminaryParsingOnly, prismContext); - } - if (QNameUtil.match(filterQName, KEY_FILTER_REF)) { - return parseRefFilter(xsubnode, pcd, preliminaryParsingOnly, prismContext); + // trivial filters + if (QNameUtil.match(clauseQName, CLAUSE_ALL)) { + return new AllFilter(); + } else if (QNameUtil.match(clauseQName, CLAUSE_NONE)) { + return new NoneFilter(); + } else if (QNameUtil.match(clauseQName, CLAUSE_UNDEFINED)) { + return new UndefinedFilter(); } - if (QNameUtil.match(filterQName, KEY_FILTER_SUBSTRING)) { - return parseSubstringFilter(xsubnode, pcd, preliminaryParsingOnly, prismContext); - } + // primitive filters + MapXNode clauseXMap = toMap(clauseContent); - if (QNameUtil.match(filterQName, KEY_FILTER_ORG)) { - return parseOrgFilter(xsubnode, pcd, preliminaryParsingOnly, prismContext); - } - - if (QNameUtil.match(filterQName, KEY_FILTER_TYPE)) { - return parseTypeFilter(xsubnode, pcd, preliminaryParsingOnly, prismContext); + if (QNameUtil.match(clauseQName, CLAUSE_EQUAL) + || QNameUtil.match(clauseQName, CLAUSE_GREATER) + || QNameUtil.match(clauseQName, CLAUSE_GREATER_OR_EQUAL) + || QNameUtil.match(clauseQName, CLAUSE_LESS) + || QNameUtil.match(clauseQName, CLAUSE_LESS_OR_EQUAL)) { + return parseComparisonFilter(clauseQName, clauseXMap, pcd, preliminaryParsingOnly, prismContext); + } else if (QNameUtil.match(clauseQName, CLAUSE_SUBSTRING)) { + return parseSubstringFilter(clauseXMap, pcd, preliminaryParsingOnly, prismContext); + } else if (QNameUtil.match(clauseQName, CLAUSE_REF)) { + return parseRefFilter(clauseXMap, pcd, preliminaryParsingOnly, prismContext); + } else if (QNameUtil.match(clauseQName, CLAUSE_ORG)) { + return parseOrgFilter(clauseXMap, pcd, preliminaryParsingOnly, prismContext); + } else if (QNameUtil.match(clauseQName, CLAUSE_IN_OID)) { + return parseInOidFilter(clauseXMap, pcd, preliminaryParsingOnly, prismContext); } - - if (QNameUtil.match(filterQName, KEY_FILTER_IN_OID)) { - return parseInOidFilter(xsubnode, pcd, preliminaryParsingOnly, prismContext); + + // logical filters + + if (QNameUtil.match(clauseQName, CLAUSE_AND)) { + return parseAndFilter(clauseXMap, pcd, preliminaryParsingOnly, prismContext); + } else if (QNameUtil.match(clauseQName, CLAUSE_OR)) { + return parseOrFilter(clauseXMap, pcd, preliminaryParsingOnly, prismContext); + } else if (QNameUtil.match(clauseQName, CLAUSE_NOT)) { + return parseNotFilter(clauseXMap, pcd, preliminaryParsingOnly, prismContext); } - if (QNameUtil.match(filterQName, KEY_FILTER_NONE_TYPE)) { - return new NoneFilter(); + // other complex filters + + if (QNameUtil.match(clauseQName, CLAUSE_TYPE)) { + return parseTypeFilter(clauseXMap, pcd, preliminaryParsingOnly, prismContext); + } else if (QNameUtil.match(clauseQName, CLAUSE_EXISTS)) { + return parseExistsFilter(clauseXMap, pcd, preliminaryParsingOnly, prismContext); } - throw new UnsupportedOperationException("Unsupported query filter " + filterQName); + throw new UnsupportedOperationException("Unsupported query filter " + clauseQName); } - private static AndFilter parseAndFilter(XNode xnode, PrismContainerDefinition pcd, + private static AndFilter parseAndFilter(MapXNode clauseXMap, PrismContainerDefinition pcd, boolean preliminaryParsingOnly, PrismContext prismContext) throws SchemaException { - - List subfilters = parseLogicalFilter(xnode, pcd, preliminaryParsingOnly, prismContext); + List subfilters = parseLogicalFilter(clauseXMap, pcd, preliminaryParsingOnly, prismContext); if (preliminaryParsingOnly) { return null; } else { @@ -242,21 +214,20 @@ private static AndFilter parseAndFilter(XNode xnode, P } } - private static List parseLogicalFilter(XNode xnode, + private static List parseLogicalFilter(MapXNode clauseXMap, PrismContainerDefinition pcd, boolean preliminaryParsingOnly, PrismContext prismContext) throws SchemaException { List subfilters = new ArrayList(); - MapXNode xmap = toMap(xnode); - for (Entry entry : xmap.entrySet()) { + for (Entry entry : clauseXMap.entrySet()) { if (entry.getValue() instanceof ListXNode){ Iterator subNodes = ((ListXNode) entry.getValue()).iterator(); while (subNodes.hasNext()){ - ObjectFilter subFilter = parseFilterContainer(subNodes.next(), entry.getKey(), pcd, preliminaryParsingOnly, prismContext); + ObjectFilter subFilter = parseFilterInternal(subNodes.next(), entry.getKey(), pcd, preliminaryParsingOnly, prismContext); if (!preliminaryParsingOnly) { subfilters.add(subFilter); } } } else{ - ObjectFilter subfilter = parseFilterContainer(entry.getValue(), entry.getKey(), pcd, preliminaryParsingOnly, prismContext); + ObjectFilter subfilter = parseFilterInternal(entry.getValue(), entry.getKey(), pcd, preliminaryParsingOnly, prismContext); if (!preliminaryParsingOnly) { subfilters.add(subfilter); } @@ -265,9 +236,9 @@ private static List parseLogicalFilter(X return subfilters; } - private static OrFilter parseOrFilter(XNode xnode, PrismContainerDefinition pcd, + private static OrFilter parseOrFilter(MapXNode clauseXMap, PrismContainerDefinition pcd, boolean preliminaryParsingOnly, PrismContext prismContext) throws SchemaException { - List subfilters = parseLogicalFilter(xnode, pcd, preliminaryParsingOnly, prismContext); + List subfilters = parseLogicalFilter(clauseXMap, pcd, preliminaryParsingOnly, prismContext); if (preliminaryParsingOnly) { return null; } else { @@ -275,11 +246,10 @@ private static OrFilter parseOrFilter(XNode xnode, Pri } } - private static NotFilter parseNotFilter(XNode xnode, PrismContainerDefinition pcd, + private static NotFilter parseNotFilter(MapXNode clauseXMap, PrismContainerDefinition pcd, boolean preliminaryParsingOnly, PrismContext prismContext) throws SchemaException { - MapXNode xmap = toMap(xnode); - Entry entry = singleSubEntry(xmap, "not"); - ObjectFilter subfilter = parseFilterContainer(entry.getValue(), entry.getKey(), pcd, preliminaryParsingOnly, prismContext); + Entry entry = singleSubEntry(clauseXMap, "not"); + ObjectFilter subfilter = parseFilterInternal(entry.getValue(), entry.getKey(), pcd, preliminaryParsingOnly, prismContext); if (preliminaryParsingOnly) { return null; } else { @@ -287,42 +257,65 @@ private static NotFilter parseNotFilter(XNode xnode, P } } - private static EqualFilter parseEqualFilter(XNode xnode, PrismContainerDefinition pcd, boolean preliminaryParsingOnly, PrismContext prismContext) throws SchemaException{ - LOGGER.trace("Start to parse EQUALS filter"); - MapXNode xmap = toMap(xnode); - ItemPath itemPath = getPath(xmap, prismContext); - + private static ObjectFilter parseComparisonFilter(QName clauseQName, MapXNode clauseXMap, + PrismContainerDefinition pcd, boolean preliminaryParsingOnly, PrismContext prismContext) throws SchemaException { + + boolean isEq = QNameUtil.match(clauseQName, CLAUSE_EQUAL); + boolean isGt = QNameUtil.match(clauseQName, CLAUSE_GREATER); + boolean isGtEq = QNameUtil.match(clauseQName, CLAUSE_GREATER_OR_EQUAL); + boolean isLt = QNameUtil.match(clauseQName, CLAUSE_LESS); + boolean isLtEq = QNameUtil.match(clauseQName, CLAUSE_LESS_OR_EQUAL); + + ItemPath itemPath = getPath(clauseXMap); if (itemPath == null || itemPath.isEmpty()){ throw new SchemaException("Could not convert query, because query does not contain item path."); } - - QName matchingRule = determineMatchingRule(xmap); - - if (itemPath.last() == null) { - throw new SchemaException("Cannot convert query, because query does not contain property path."); - } QName itemName = ItemPath.getName(itemPath.last()); - - XNode valueXnode = xmap.get(KEY_FILTER_VALUE); - + + QName matchingRule = getMatchingRule(clauseXMap); + + XNode valueXnode = clauseXMap.get(ELEMENT_VALUE); + ItemPath rightSidePath = getPath(clauseXMap, ELEMENT_RIGHT_HAND_SIDE_PATH); + ItemDefinition itemDefinition = locateItemDefinition(valueXnode, itemPath, pcd, prismContext); if (itemDefinition != null){ itemName = itemDefinition.getName(); } if (valueXnode != null) { - Item item = parseItem(valueXnode, itemName, itemDefinition, prismContext); - if (preliminaryParsingOnly) { - return null; + if (!isEq && item.getValues().size() != 1) { + throw new SchemaException("Expected exactly one value, got " + item.getValues().size() + " instead"); + } + if (preliminaryParsingOnly) { + return null; } else { - return EqualFilter.createEqual(itemPath, (PrismProperty) item, matchingRule); + if (isEq) { + return EqualFilter.createEqual(itemPath, (PrismProperty) item, matchingRule); + } + PrismPropertyValue propertyValue = (PrismPropertyValue) item.getValue(0); + if (isGt || isGtEq) { + return GreaterFilter.createGreater(itemPath, pcd, propertyValue, isGtEq); + } else { + return LessFilter.createLess(itemPath, pcd, propertyValue, isLtEq); + } } - + } else if (rightSidePath != null) { + if (preliminaryParsingOnly) { + return null; + } else { + ItemDefinition rightSideDefinition = pcd != null ? pcd.findItemDefinition(rightSidePath) : null; + if (isEq) { + return EqualFilter.createEqual(itemPath, (PrismPropertyDefinition) itemDefinition, matchingRule, rightSidePath, rightSideDefinition); + } else if (isGt || isGtEq) { + return GreaterFilter.createGreater(itemPath, (PrismPropertyDefinition) itemDefinition, rightSidePath, rightSideDefinition, isGtEq); + } else { + return LessFilter.createLess(itemPath, (PrismPropertyDefinition) itemDefinition, rightSidePath, rightSideDefinition, isLtEq); + } + } } else { - - Entry expressionEntry = xmap.getSingleEntryThatDoesNotMatch( - KEY_FILTER_VALUE, KEY_FILTER_EQUAL_MATCHING, KEY_FILTER_EQUAL_PATH); + Entry expressionEntry = clauseXMap.getSingleEntryThatDoesNotMatch( + ELEMENT_VALUE, ELEMENT_MATCHING, ELEMENT_PATH); if (expressionEntry != null) { PrismPropertyValue expressionPropertyValue = prismContext.getXnodeProcessor().parsePrismPropertyFromGlobalXNodeValue( expressionEntry, ParsingContext.createDefault()); @@ -331,24 +324,32 @@ private static EqualFilter parseEqualFilter(XNode } else { ExpressionWrapper expressionWrapper = new ExpressionWrapper(); expressionWrapper.setExpression(expressionPropertyValue.getValue()); - return EqualFilter.createEqual(itemPath, (PrismPropertyDefinition) itemDefinition, matchingRule, expressionWrapper); + if (isEq) { + return EqualFilter.createEqual(itemPath, (PrismPropertyDefinition) itemDefinition, matchingRule, expressionWrapper); + } else if (isGt || isGtEq) { + return GreaterFilter.createGreater(itemPath, (PrismPropertyDefinition) itemDefinition, expressionWrapper, isGtEq); + } else { + return LessFilter.createLess(itemPath, (PrismPropertyDefinition) itemDefinition, expressionWrapper, isLtEq); + } } } else { + if (!isEq) { + throw new SchemaException("Comparison filter (greater, less) requires at least one value expression."); + } if (preliminaryParsingOnly) { return null; } else { - return EqualFilter.createNullEqual(itemPath, (PrismPropertyDefinition) itemDefinition, matchingRule); + return EqualFilter.createNullEqual(itemPath, (PrismPropertyDefinition) itemDefinition, matchingRule); } } } - } - private static InOidFilter parseInOidFilter(XNode xnode, PrismContainerDefinition pcd, boolean preliminaryParsingOnly, PrismContext prismContext) throws SchemaException{ - - MapXNode xmap = toMap(xnode); + private static InOidFilter parseInOidFilter(MapXNode clauseXMap, PrismContainerDefinition pcd, boolean preliminaryParsingOnly, PrismContext prismContext) throws SchemaException{ + + boolean considerOwner = Boolean.TRUE.equals(clauseXMap.getParsedPrimitiveValue(ELEMENT_CONSIDER_OWNER, DOMUtil.XSD_BOOLEAN)); - XNode valueXnode = xmap.get(KEY_FILTER_VALUE); + XNode valueXnode = clauseXMap.get(ELEMENT_VALUE); if (valueXnode != null) { List oids = new ArrayList<>(); if (valueXnode instanceof ListXNode) { @@ -364,101 +365,83 @@ private static InOidFilter parseInOidFilter(XNode xnode, PrismContainerDefinitio } else { throw new SchemaException("The OID was expected to be present as primitive or list XNode, instead it is: " + valueXnode); } - InOidFilter inOidFilter = InOidFilter.createInOid(oids); - return inOidFilter; - + return InOidFilter.createInOid(considerOwner, oids); } else { - - ExpressionWrapper expression = parseExpression(xmap, prismContext); + ExpressionWrapper expression = parseExpression(clauseXMap, prismContext); if (expression != null) { - InOidFilter inOidFilter = InOidFilter.createInOid(expression); - return inOidFilter; + return InOidFilter.createInOid(considerOwner, expression); } else { throw new SchemaException("InOid filter with no values nor expression"); } } } - private static TypeFilter parseTypeFilter(XNode xnode, PrismContainerDefinition pcd, boolean preliminaryParsingOnly, PrismContext prismContext) throws SchemaException{ - MapXNode xmap = toMap(xnode); - QName type = xmap.getParsedPrimitiveValue(KEY_FILTER_TYPE_TYPE, DOMUtil.XSD_QNAME); + private static TypeFilter parseTypeFilter(MapXNode clauseXMap, PrismContainerDefinition pcd, boolean preliminaryParsingOnly, PrismContext prismContext) throws SchemaException{ + QName type = clauseXMap.getParsedPrimitiveValue(ELEMENT_TYPE, DOMUtil.XSD_QNAME); - XNode subXFilter = xmap.get(KEY_FILTER_TYPE_FILTER); - ObjectFilter subFilter = null; + XNode subXFilter = clauseXMap.get(ELEMENT_FILTER); PrismObjectDefinition def = prismContext.getSchemaRegistry().findObjectDefinitionByType(type); + ObjectFilter subFilter = null; if (subXFilter != null && subXFilter instanceof MapXNode) { - subFilter = parseFilter((MapXNode) subXFilter, def); + subFilter = parseFilterInternal((MapXNode) subXFilter, def, preliminaryParsingOnly, prismContext); } - if (preliminaryParsingOnly) { return null; } else { return new TypeFilter(type, subFilter); } } - - - private static RefFilter parseRefFilter(XNode xnode, PrismContainerDefinition pcd, boolean preliminaryParsingOnly, PrismContext prismContext) throws SchemaException{ - MapXNode xmap = toMap(xnode); - ItemPath itemPath = getPath(xmap, prismContext); - - if (itemPath == null || itemPath.isEmpty()){ - throw new SchemaException("Cannot convert query, because query does not contain property path."); + + private static ExistsFilter parseExistsFilter(MapXNode clauseXMap, PrismContainerDefinition pcd, boolean preliminaryParsingOnly, PrismContext prismContext) throws SchemaException{ + ItemPath path = getPath(clauseXMap); + + XNode subXFilter = clauseXMap.get(ELEMENT_FILTER); + ObjectFilter subFilter = null; + PrismContainerDefinition subPcd = pcd != null ? pcd.findContainerDefinition(path) : null; + if (subXFilter != null && subXFilter instanceof MapXNode) { + subFilter = parseFilterInternal((MapXNode) subXFilter, subPcd, preliminaryParsingOnly, prismContext); } + if (preliminaryParsingOnly) { + return null; + } else { + return ExistsFilter.createExists(path, pcd, subFilter); + } + } + + private static RefFilter parseRefFilter(MapXNode clauseXMap, PrismContainerDefinition pcd, boolean preliminaryParsingOnly, PrismContext prismContext) throws SchemaException{ + ItemPath itemPath = getPath(clauseXMap); - if (itemPath.last() == null){ + if (itemPath == null || itemPath.isEmpty()){ throw new SchemaException("Cannot convert query, because query does not contain property path."); } - QName itemName = ItemPath.getName(itemPath.last()); - ItemPath parentPath = itemPath.allExceptLast(); - if (parentPath.isEmpty()){ - parentPath = null; - } - + ItemDefinition itemDefinition = null; if (pcd != null) { - itemDefinition = pcd.findItemDefinition(itemPath); - if (itemDefinition == null) { + itemDefinition = pcd != null ? pcd.findItemDefinition(itemPath) : null; + if (itemDefinition == null && !preliminaryParsingOnly) { throw new SchemaException("No definition for item "+itemPath+" in "+pcd); } } - - XNode valueXnode = xmap.get(KEY_FILTER_VALUE); - if (valueXnode != null){ - + XNode valueXnode = clauseXMap.get(ELEMENT_VALUE); + if (valueXnode != null) { Item item = prismContext.getXnodeProcessor().parseItem(valueXnode, itemName, itemDefinition, ParsingContext.allowMissingRefTypes()); - - if (preliminaryParsingOnly) { - return null; - } - - PrismReference ref = (PrismReference)item; - - if (item.getValues().size() < 1 ) { - throw new IllegalStateException("No values to search specified for item " + itemName); - } - - ExpressionWrapper expressionWrapper = null; - // TODO implement expressions - don't forget preliminary mode! - - return RefFilter.createReferenceEqual(itemPath, ref, expressionWrapper); - + if (preliminaryParsingOnly) { + return null; + } + PrismReference ref = (PrismReference)item; + if (item.getValues().size() < 1) { + throw new IllegalStateException("No values to search specified for item " + itemName); + } + return RefFilter.createReferenceEqual(itemPath, ref, null); } else { - ExpressionWrapper expressionWrapper = parseExpression(xmap, prismContext); -// Entry expressionEntry = xmap.getSingleEntryThatDoesNotMatch( -// -// KEY_FILTER_VALUE, KEY_FILTER_EQUAL_MATCHING, KEY_FILTER_EQUAL_PATH); + ExpressionWrapper expressionWrapper = parseExpression(clauseXMap, prismContext); if (expressionWrapper != null) { -// PrismPropertyValue expressionPropertyValue = prismContext.getXnodeProcessor() -// .parsePrismPropertyFromGlobalXNodeValue(expressionEntry); if (preliminaryParsingOnly) { return null; } else { -// ExpressionWrapper expressionWrapper = new ExpressionWrapper(); -// expressionWrapper.setExpression(expressionPropertyValue.getValue()); return RefFilter.createReferenceEqual(itemPath, (PrismReferenceDefinition) itemDefinition, expressionWrapper); } @@ -466,19 +449,17 @@ private static RefFilter parseRefFilter(XNode xnode, P if (preliminaryParsingOnly) { return null; } else { -// ExpressionWrapper expressionWrapper = null; return RefFilter.createReferenceEqual(itemPath, (PrismReferenceDefinition) itemDefinition, expressionWrapper); } } } - } private static ExpressionWrapper parseExpression(MapXNode xmap, PrismContext prismContext) throws SchemaException { Entry expressionEntry = xmap.getSingleEntryThatDoesNotMatch( - KEY_FILTER_VALUE, KEY_FILTER_EQUAL_MATCHING, KEY_FILTER_EQUAL_PATH); + ELEMENT_VALUE, ELEMENT_MATCHING, ELEMENT_PATH); if (expressionEntry != null) { PrismPropertyValue expressionPropertyValue = prismContext.getXnodeProcessor() .parsePrismPropertyFromGlobalXNodeValue(expressionEntry, ParsingContext.createDefault()); @@ -491,35 +472,28 @@ private static ExpressionWrapper parseExpression(MapXNode xmap, PrismContext pri } - private static SubstringFilter parseSubstringFilter(XNode xnode, PrismContainerDefinition pcd, boolean preliminaryParsingOnly, PrismContext prismContext) + private static SubstringFilter parseSubstringFilter(MapXNode clauseXMap, PrismContainerDefinition pcd, boolean preliminaryParsingOnly, PrismContext prismContext) throws SchemaException { - MapXNode xmap = toMap(xnode); - ItemPath itemPath = getPath(xmap, prismContext); + ItemPath itemPath = getPath(clauseXMap); if (itemPath == null || itemPath.isEmpty()){ throw new SchemaException("Could not convert query, because query does not contain item path."); } - - QName matchingRule = determineMatchingRule(xmap); - - if (itemPath.last() == null){ - throw new SchemaException("Cannot convert query, becasue query does not contian property path."); - } QName itemName = ItemPath.getName(itemPath.last()); - - - XNode valueXnode = xmap.get(KEY_FILTER_VALUE); + QName matchingRule = getMatchingRule(clauseXMap); + + XNode valueXnode = clauseXMap.get(ELEMENT_VALUE); ItemDefinition itemDefinition = locateItemDefinition(valueXnode, itemPath, pcd, prismContext); Item item = parseItem(valueXnode, itemName, itemDefinition, prismContext); - Boolean anchorStart = xmap.getParsedPrimitiveValue(KEY_FILTER_SUBSTRING_ANCHOR_START, DOMUtil.XSD_BOOLEAN); + Boolean anchorStart = clauseXMap.getParsedPrimitiveValue(ELEMENT_ANCHOR_START, DOMUtil.XSD_BOOLEAN); if (anchorStart == null) { anchorStart = false; } - Boolean anchorEnd = xmap.getParsedPrimitiveValue(KEY_FILTER_SUBSTRING_ANCHOR_END, DOMUtil.XSD_BOOLEAN); + Boolean anchorEnd = clauseXMap.getParsedPrimitiveValue(ELEMENT_ANCHOR_END, DOMUtil.XSD_BOOLEAN); if (anchorEnd == null) { anchorEnd = false; } @@ -531,10 +505,8 @@ private static SubstringFilter parseSubstringFilter(XN } } - private static OrgFilter parseOrgFilter(XNode xnode, PrismContainerDefinition pcd, boolean preliminaryParsingOnly, PrismContext prismContext) throws SchemaException { - MapXNode xmap = toMap(xnode); - - if (Boolean.TRUE.equals(xmap.getParsedPrimitiveValue(KEY_FILTER_ORG_IS_ROOT, DOMUtil.XSD_BOOLEAN))) { + private static OrgFilter parseOrgFilter(MapXNode clauseXMap, PrismContainerDefinition pcd, boolean preliminaryParsingOnly, PrismContext prismContext) throws SchemaException { + if (Boolean.TRUE.equals(clauseXMap.getParsedPrimitiveValue(ELEMENT_IS_ROOT, DOMUtil.XSD_BOOLEAN))) { // TODO check if other content is present if (preliminaryParsingOnly) { return null; @@ -543,21 +515,19 @@ private static OrgFilter parseOrgFilter(XNode xnode, P } } - XNode xorgrefnode = xmap.get(KEY_FILTER_ORG_REF); + XNode xorgrefnode = clauseXMap.get(ELEMENT_ORG_REF); if (xorgrefnode == null) { throw new SchemaException("No organization reference defined in the search query."); } MapXNode xorgrefmap = toMap(xorgrefnode); - String orgOid = xorgrefmap.getParsedPrimitiveValue(KEY_FILTER_ORG_REF_OID, DOMUtil.XSD_STRING); + String orgOid = xorgrefmap.getParsedPrimitiveValue(ELEMENT_OID, DOMUtil.XSD_STRING); if (orgOid == null || StringUtils.isBlank(orgOid)) { throw new SchemaException("No oid attribute defined in the organization reference element."); } - XsdTypeMapper.getTypeFromClass(Scope.class); - - String scopeString = xorgrefmap.getParsedPrimitiveValue(KEY_FILTER_ORG_SCOPE, DOMUtil.XSD_STRING); // original (in my opinion incorrect) place + String scopeString = xorgrefmap.getParsedPrimitiveValue(ELEMENT_SCOPE, DOMUtil.XSD_STRING); // original (in my opinion incorrect) place if (scopeString == null) { - scopeString = xmap.getParsedPrimitiveValue(KEY_FILTER_ORG_SCOPE, DOMUtil.XSD_STRING); // here it is placed by the serializer + scopeString = clauseXMap.getParsedPrimitiveValue(ELEMENT_SCOPE, DOMUtil.XSD_STRING); // here it is placed by the serializer } Scope scope = scopeString != null ? Scope.valueOf(scopeString) : null; @@ -589,23 +559,23 @@ private static PrimitiveXNode toPrimitive(XNode xnode, XNode context) throws Sch return (PrimitiveXNode)xnode; } - private static ItemPath getPath(MapXNode xmap, PrismContext prismContext) throws SchemaException { - XNode xnode = xmap.get(KEY_FILTER_EQUAL_PATH); + private static ItemPath getPath(MapXNode clauseXMap) throws SchemaException { + return getPath(clauseXMap, ELEMENT_PATH); + } + + private static ItemPath getPath(MapXNode clauseXMap, QName key) throws SchemaException { + XNode xnode = clauseXMap.get(key); if (xnode == null) { return null; } if (!(xnode instanceof PrimitiveXNode)) { - throw new SchemaException("Expected that field "+KEY_FILTER_EQUAL_PATH+" will be primitive, but it is "+xnode.getDesc()); + throw new SchemaException("Expected that field "+key+" will be primitive, but it is "+xnode.getDesc()); } -// XNodeProcessor processor = PrismUtil.getXnodeProcessor(prismContext); -// return processor.parseAtomicValue(xnode, new PrismPropertyDefinition(ItemPathType.COMPLEX_TYPE, ItemPathType.COMPLEX_TYPE, prismContext)); -// return ipt.getItemPath(); - return xmap.getParsedPrimitiveValue(KEY_FILTER_EQUAL_PATH, ItemPath.XSD_TYPE); -// return itemPathType.getItemPath(); + return clauseXMap.getParsedPrimitiveValue(key, ItemPath.XSD_TYPE); } - private static QName determineMatchingRule(MapXNode xmap) throws SchemaException{ - String matchingRuleString = xmap.getParsedPrimitiveValue(KEY_FILTER_EQUAL_MATCHING, DOMUtil.XSD_STRING); + private static QName getMatchingRule(MapXNode xmap) throws SchemaException{ + String matchingRuleString = xmap.getParsedPrimitiveValue(ELEMENT_MATCHING, DOMUtil.XSD_STRING); if (StringUtils.isNotBlank(matchingRuleString)){ if (QNameUtil.isUri(matchingRuleString)) { return QNameUtil.uriToQName(matchingRuleString); @@ -633,7 +603,6 @@ private static Item parseItem(XNode valueXnode, QName itemName, ItemDefinition i } private static ItemDefinition locateItemDefinition(XNode valueXnode, ItemPath itemPath, PrismContainerDefinition pcd, PrismContext prismContext) throws SchemaException{ -// QName itemName = ItemPath.getName(itemPath.last()); // TODO why using only the last item name? It can be in a container different from 'pcd' ItemDefinition itemDefinition = null; if (pcd != null) { itemDefinition = pcd.findItemDefinition(itemPath); @@ -648,9 +617,6 @@ private static ItemDefinition locateItemDefinition(XNo return locateItemDefinition(valueXnode, rest, (PrismContainerDefinition) itemDefinition, prismContext); } } - // do not throw...it will be saved as raw.. -// if (itemDefinition == null){ -// throw new SchemaException("No definition for item "+itemPath+" in "+pcd); } } return itemDefinition; @@ -665,64 +631,55 @@ public static MapXNode serializeFilter(ObjectFilter filter, PrismContext prismCo return serializeFilter(filter, PrismUtil.getXnodeProcessor(prismContext).createSerializer()); } - public static MapXNode serializeFilter(ObjectFilter filter, XNodeSerializer xnodeSerializer) throws SchemaException{ + private static MapXNode serializeFilter(ObjectFilter filter, XNodeSerializer xnodeSerializer) throws SchemaException{ + // null or primitive filters if (filter == null) { return null; + } else if (filter instanceof AllFilter) { + return serializeAllFilter(); + } else if (filter instanceof NoneFilter) { + return serializeNoneFilter(); + } else if (filter instanceof UndefinedFilter) { + return serializeUndefinedFilter(); + } else if (filter instanceof EqualFilter + || filter instanceof GreaterFilter + || filter instanceof LessFilter) { + return serializeComparisonFilter((PropertyValueFilter) filter, xnodeSerializer); + } else if (filter instanceof SubstringFilter) { + return serializeSubstringFilter((SubstringFilter) filter, xnodeSerializer); + } else if (filter instanceof RefFilter) { + return serializeRefFilter((RefFilter) filter, xnodeSerializer); + } else if (filter instanceof OrgFilter) { + return serializeOrgFilter((OrgFilter) filter, xnodeSerializer); + } else if (filter instanceof InOidFilter) { + return serializeInOidFilter((InOidFilter) filter, xnodeSerializer); } - + + // complex filters if (filter instanceof AndFilter) { return serializeAndFilter((AndFilter) filter, xnodeSerializer); - } - if (filter instanceof OrFilter) { + } else if (filter instanceof OrFilter) { return serializeOrFilter((OrFilter) filter, xnodeSerializer); - } - if (filter instanceof NotFilter) { + } else if (filter instanceof NotFilter) { return serializeNotFilter((NotFilter) filter, xnodeSerializer); } - if (filter instanceof EqualFilter) { - return serializeEqualsFilter((EqualFilter) filter, xnodeSerializer); - } - if (filter instanceof RefFilter) { - return serializeRefFilter((RefFilter) filter, xnodeSerializer); - } - - if (filter instanceof SubstringFilter) { - return serializeSubstringFilter((SubstringFilter) filter, xnodeSerializer); - } - if (filter instanceof OrgFilter) { - return serializeOrgFilter((OrgFilter) filter, xnodeSerializer); - } - if (filter instanceof TypeFilter) { return serializeTypeFilter((TypeFilter) filter, xnodeSerializer); + } else if (filter instanceof ExistsFilter) { + return serializeExistsFilter((ExistsFilter) filter, xnodeSerializer); } - if (filter instanceof NoneFilter) { - return serializeNoneFilter((NoneFilter) filter, xnodeSerializer); - } - - if (filter instanceof AllFilter) { - return serializeAllFilter((AllFilter) filter, xnodeSerializer); - } - - if (filter instanceof InOidFilter) { - return serializeInOidFilter((InOidFilter) filter, xnodeSerializer); - } - throw new UnsupportedOperationException("Unsupported filter type: " + filter); } private static MapXNode serializeAndFilter(AndFilter filter, XNodeSerializer xnodeSerilizer) throws SchemaException{ - MapXNode map = new MapXNode(); - map.put(KEY_FILTER_AND, serializeNaryLogicalSubfilters(filter.getConditions(), xnodeSerilizer)); - return map; + return createFilter(CLAUSE_AND, serializeNaryLogicalSubfilters(filter.getConditions(), xnodeSerilizer)); } private static MapXNode serializeOrFilter(OrFilter filter, XNodeSerializer xnodeSerilizer) throws SchemaException{ - MapXNode map = new MapXNode(); - map.put(KEY_FILTER_OR, serializeNaryLogicalSubfilters(filter.getConditions(), xnodeSerilizer)); + MapXNode map = createFilter(CLAUSE_OR, serializeNaryLogicalSubfilters(filter.getConditions(), xnodeSerilizer)); return map; } @@ -736,61 +693,78 @@ private static MapXNode serializeNaryLogicalSubfilters(List object } private static MapXNode serializeNotFilter(NotFilter filter, XNodeSerializer xnodeSerializer) throws SchemaException{ + return createFilter(CLAUSE_NOT, serializeFilter(filter.getFilter(), xnodeSerializer)); + } + + @NotNull + private static MapXNode createFilter(QName clauseNot, MapXNode value) { MapXNode map = new MapXNode(); - map.put(KEY_FILTER_NOT, serializeFilter(filter.getFilter(), xnodeSerializer)); + map.put(clauseNot, value); return map; } private static MapXNode serializeInOidFilter(InOidFilter filter, XNodeSerializer xnodeSerializer) throws SchemaException { - MapXNode filterMap = new MapXNode(); - - MapXNode contentsMap = new MapXNode(); - + MapXNode clauseMap = new MapXNode(); if (filter.getOids() != null && !filter.getOids().isEmpty()) { ListXNode valuesNode = new ListXNode(); for (String oid : filter.getOids()) { XNode val = createPrimitiveXNode(oid, DOMUtil.XSD_STRING); valuesNode.add(val); } - contentsMap.put(KEY_FILTER_VALUE, valuesNode); + clauseMap.put(ELEMENT_VALUE, valuesNode); } else if (filter.getExpression() != null) { // TODO serialize expression } else { throw new SchemaException("InOid filter with no values nor expression"); } + if (filter.isConsiderOwner()) { + clauseMap.put(ELEMENT_CONSIDER_OWNER, new PrimitiveXNode<>(true)); + } - filterMap.put(KEY_FILTER_IN_OID, contentsMap); - return filterMap; + return createFilter(CLAUSE_IN_OID, clauseMap); } - private static MapXNode serializeEqualsFilter(EqualFilter filter, XNodeSerializer xnodeSerializer) throws SchemaException{ + private static MapXNode serializeComparisonFilter(PropertyValueFilter filter, XNodeSerializer xnodeSerializer) throws SchemaException{ MapXNode map = new MapXNode(); - map.put(KEY_FILTER_EQUAL, serializeValueFilter(filter, xnodeSerializer)); + QName clause; + if (filter instanceof EqualFilter) { + clause = CLAUSE_EQUAL; + } else if (filter instanceof GreaterFilter) { + clause = ((GreaterFilter) filter).isEquals() ? CLAUSE_GREATER_OR_EQUAL : CLAUSE_GREATER; + } else if (filter instanceof LessFilter) { + clause = ((LessFilter) filter).isEquals() ? CLAUSE_LESS_OR_EQUAL : CLAUSE_LESS; + } else { + throw new IllegalStateException(); + } + map.put(clause, serializeValueFilter(filter, xnodeSerializer)); return map; } private static MapXNode serializeValueFilter(PropertyValueFilter filter, XNodeSerializer xnodeSerializer) throws SchemaException { MapXNode map = new MapXNode(); serializeMatchingRule(filter, map); - - serializePath(filter, map); + serializePath(map, filter.getFullPath(), filter); - ListXNode valuesNode = new ListXNode(); - List values = filter.getValues(); if (values != null) { + ListXNode valuesNode = new ListXNode(); for (T val : values) { if (val.getParent() == null) { val.setParent(filter); } - XNode valNode = null; - - valNode = xnodeSerializer.serializeItemValue(val, filter.getDefinition()); - + XNode valNode = xnodeSerializer.serializeItemValue(val, filter.getDefinition()); + if (filter instanceof RefFilter) { // TODO shouldn't we do this in all cases? + valNode.setExplicitTypeDeclaration(true); + if (valNode.getTypeQName() == null) { + valNode.setTypeQName(ObjectReferenceType.COMPLEX_TYPE); + } + } valuesNode.add(valNode); } - - map.put(KEY_FILTER_VALUE, valuesNode); + map.put(ELEMENT_VALUE, valuesNode); + } + if (filter.getRightHandSidePath() != null) { + map.put(ELEMENT_RIGHT_HAND_SIDE_PATH, createPrimitiveXNode(filter.getRightHandSidePath(), ItemPath.XSD_TYPE)); } ExpressionWrapper xexpression = filter.getExpression(); @@ -803,86 +777,83 @@ private static MapXNode serializeValueFilter(PropertyValu } private static MapXNode serializeRefFilter(RefFilter filter, XNodeSerializer xnodeSerializer) throws SchemaException { - - MapXNode map = new MapXNode(); - - map.put(KEY_FILTER_REF, serializeValueFilter(filter, xnodeSerializer)); + MapXNode map = createFilter(CLAUSE_REF, serializeValueFilter(filter, xnodeSerializer)); return map; } private static MapXNode serializeSubstringFilter(SubstringFilter filter, XNodeSerializer xnodeSerializer) throws SchemaException{ MapXNode map = new MapXNode(); - map.put(KEY_FILTER_SUBSTRING, serializeValueFilter(filter, xnodeSerializer)); + MapXNode content = serializeValueFilter(filter, xnodeSerializer); + if (filter.isAnchorStart()) { + content.put(ELEMENT_ANCHOR_START, new PrimitiveXNode<>(true)); + } + if (filter.isAnchorEnd()) { + content.put(ELEMENT_ANCHOR_END, new PrimitiveXNode<>(true)); + } + map.put(CLAUSE_SUBSTRING, content); return map; } - private static MapXNode serializeTypeFilter(TypeFilter filter, XNodeSerializer xnodeSerializer) throws SchemaException{ - MapXNode map = new MapXNode(); - map.put(KEY_FILTER_TYPE_TYPE, createPrimitiveXNode(filter.getType(), DOMUtil.XSD_QNAME)); - - MapXNode subXFilter = null; + MapXNode content = new MapXNode(); + content.put(ELEMENT_TYPE, createPrimitiveXNode(filter.getType(), DOMUtil.XSD_QNAME)); if (filter.getFilter() != null){ - subXFilter = serializeFilter(filter.getFilter(), xnodeSerializer); - map.put(KEY_FILTER_TYPE_FILTER, subXFilter); + content.put(ELEMENT_FILTER, serializeFilter(filter.getFilter(), xnodeSerializer)); } - - MapXNode xtypeFilter= new MapXNode(); - xtypeFilter.put(KEY_FILTER_TYPE, map); - return xtypeFilter; - + return createFilter(CLAUSE_TYPE, content); } - - private static MapXNode serializeNoneFilter(NoneFilter filter, XNodeSerializer xnodeSerializer) { - MapXNode map = new MapXNode(); - map.put(KEY_FILTER_NONE_TYPE, new MapXNode()); - return map; + + private static MapXNode serializeExistsFilter(ExistsFilter filter, XNodeSerializer xnodeSerializer) throws SchemaException{ + MapXNode content = new MapXNode(); + serializePath(content, filter.getFullPath(), filter); + if (filter.getFilter() != null){ + content.put(ELEMENT_FILTER, serializeFilter(filter.getFilter(), xnodeSerializer)); + } + return createFilter(CLAUSE_EXISTS, content); } - + private static MapXNode serializeOrgFilter(OrgFilter filter, XNodeSerializer xnodeSerializer) { MapXNode map = new MapXNode(); if (filter.getOrgRef() != null) { MapXNode orgRefMap = new MapXNode(); - orgRefMap.put(KEY_FILTER_ORG_REF_OID, createPrimitiveXNode(filter.getOrgRef().getOid(), DOMUtil.XSD_STRING)); - map.put(KEY_FILTER_ORG_REF, orgRefMap); + orgRefMap.put(ELEMENT_OID, createPrimitiveXNode(filter.getOrgRef().getOid(), DOMUtil.XSD_STRING)); + map.put(ELEMENT_ORG_REF, orgRefMap); } if (filter.getScope() != null) { - map.put(KEY_FILTER_ORG_SCOPE, createPrimitiveXNode(filter.getScope().name(), DOMUtil.XSD_STRING)); + map.put(ELEMENT_SCOPE, createPrimitiveXNode(filter.getScope().name(), DOMUtil.XSD_STRING)); } if (filter.isRoot()) { - map.put(KEY_FILTER_ORG_IS_ROOT, createPrimitiveXNode(Boolean.TRUE, DOMUtil.XSD_BOOLEAN)); + map.put(ELEMENT_IS_ROOT, createPrimitiveXNode(Boolean.TRUE, DOMUtil.XSD_BOOLEAN)); } - - MapXNode xtypeFilter= new MapXNode(); - xtypeFilter.put(KEY_FILTER_ORG, map); - return xtypeFilter; + + return createFilter(CLAUSE_ORG, map); } - - - - private static MapXNode serializeAllFilter(AllFilter filter, XNodeSerializer xnodeSerializer) throws SchemaException{ - MapXNode xtypeFilter= new MapXNode(); - xtypeFilter.put(KEY_FILTER_ALL, null); - return xtypeFilter; - + + private static MapXNode serializeAllFilter() { + return createFilter(CLAUSE_ALL, new MapXNode()); } - private static void serializeMatchingRule(ValueFilter filter, MapXNode map){ + private static MapXNode serializeNoneFilter() { + return createFilter(CLAUSE_NONE, new MapXNode()); + } + + private static MapXNode serializeUndefinedFilter() { + return createFilter(CLAUSE_UNDEFINED, new MapXNode()); + } + + private static void serializeMatchingRule(ValueFilter filter, MapXNode map) { if (filter.getMatchingRule() != null){ PrimitiveXNode matchingNode = createPrimitiveXNode(filter.getMatchingRule().getLocalPart(), DOMUtil.XSD_STRING); - map.put(KEY_FILTER_EQUAL_MATCHING, matchingNode); + map.put(ELEMENT_MATCHING, matchingNode); } - } - private static void serializePath(ValueFilter filter, MapXNode map) { - if (filter.getFullPath() == null){ - throw new IllegalStateException("Cannot serialize filter " + filter +" because it does not contain path"); + private static void serializePath(MapXNode map, ItemPath path, ObjectFilter filter) { + if (path == null) { + throw new IllegalStateException("Cannot serialize filter " + filter + " because it does not contain path"); } - PrimitiveXNode pathNode = createPrimitiveXNode(filter.getFullPath(), ItemPath.XSD_TYPE); - - map.put(KEY_FILTER_EQUAL_PATH, pathNode); + map.put(ELEMENT_PATH, createPrimitiveXNode(path, ItemPath.XSD_TYPE)); } private static XNode serializePropertyValue(PrismPropertyValue value, PrismPropertyDefinition definition, PrismBeanConverter beanConverter) throws SchemaException { @@ -897,12 +868,13 @@ private static XNode serializePropertyValue(PrismPropertyValue value, Pri } private static PrimitiveXNode createPrimitiveXNode(T val, QName type) { - PrimitiveXNode xprim = new PrimitiveXNode(); + PrimitiveXNode xprim = new PrimitiveXNode<>(); xprim.setValue(val, type); return xprim; } + // TODO what with this? [med] public static void revive (ObjectFilter filter, final PrismContext prismContext) throws SchemaException { // Visitor visitor = new Visitor() { // @Override @@ -933,6 +905,6 @@ public static void revive (ObjectFilter filter, final PrismContext prismContext) * @param prismContext */ public static void parseFilterPreliminarily(MapXNode xfilter, PrismContext prismContext) throws SchemaException { - parseFilterContainer(xfilter, null, true, prismContext); + parseFilterInternal(xfilter, null, true, prismContext); } } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/XPathHolder.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/XPathHolder.java index 0b10c92ede7..5e20711dce9 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/XPathHolder.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/XPathHolder.java @@ -29,7 +29,8 @@ import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; -import com.evolveum.midpoint.prism.path.IdItemPathSegment; +import com.evolveum.midpoint.prism.PrismConstants; +import com.evolveum.midpoint.prism.path.*; import com.evolveum.midpoint.util.QNameUtil; import org.apache.commons.lang.StringUtils; @@ -38,9 +39,6 @@ import org.w3c.dom.Element; import org.w3c.dom.Node; -import com.evolveum.midpoint.prism.path.ItemPath; -import com.evolveum.midpoint.prism.path.ItemPathSegment; -import com.evolveum.midpoint.prism.path.NameItemPathSegment; import com.evolveum.midpoint.prism.xml.GlobalDynamicNamespacePrefixMapper; import com.evolveum.midpoint.util.DOMUtil; import com.evolveum.midpoint.util.exception.SystemException; @@ -109,7 +107,7 @@ public XPathHolder(String xpath, Node domNode) { */ private void parse(String xpath, Node domNode, Map namespaceMap) { - segments = new ArrayList(); + segments = new ArrayList<>(); absolute = false; if (".".equals(xpath)) { @@ -168,9 +166,17 @@ private void parse(String xpath, Node domNode, Map namespaceMap) } QName qname; if (qnameArray.length == 1 || qnameArray[1] == null || qnameArray[1].isEmpty()) { - // default namespace <= empty prefix - String namespace = findNamespace(null, domNode, namespaceMap); - qname = new QName(namespace, qnameArray[0]); + if (ParentPathSegment.SYMBOL.equals(qnameArray[0])) { + qname = ParentPathSegment.QNAME; + } else if (ObjectReferencePathSegment.SYMBOL.equals(qnameArray[0])) { + qname = ObjectReferencePathSegment.QNAME; + } else if (IdentifierPathSegment.SYMBOL.equals(qnameArray[0])) { + qname = IdentifierPathSegment.QNAME; + } else { + // default namespace <= empty prefix + String namespace = findNamespace(null, domNode, namespaceMap); + qname = new QName(namespace, qnameArray[0]); + } } else { String namespacePrefix = qnameArray[0]; String namespace = findNamespace(namespacePrefix, domNode, namespaceMap); @@ -258,15 +264,23 @@ public XPathHolder(QName... segmentQNames) { } public XPathHolder(ItemPath propertyPath) { - this.segments = new ArrayList(); + this.segments = new ArrayList<>(); for (ItemPathSegment segment: propertyPath.getSegments()) { - XPathSegment xsegment = null; + XPathSegment xsegment; if (segment instanceof NameItemPathSegment) { boolean variable = ((NameItemPathSegment) segment).isVariable(); xsegment = new XPathSegment(((NameItemPathSegment)segment).getName(), variable); } else if (segment instanceof IdItemPathSegment) { xsegment = new XPathSegment(idToString(((IdItemPathSegment) segment).getId())); - } + } else if (segment instanceof ObjectReferencePathSegment) { + xsegment = new XPathSegment(PrismConstants.T_OBJECT_REFERENCE, false); + } else if (segment instanceof ParentPathSegment) { + xsegment = new XPathSegment(PrismConstants.T_PARENT, false); + } else if (segment instanceof IdentifierPathSegment) { + xsegment = new XPathSegment(PrismConstants.T_ID, false); + } else { + throw new IllegalStateException("Unknown segment: " + segment); + } this.segments.add(xsegment); } this.explicitNamespaceDeclarations = propertyPath.getNamespaceMap(); @@ -343,7 +357,14 @@ private void addPureXpath(StringBuilder sb) { sb.append("$"); } QName qname = seg.getQName(); - if (!StringUtils.isEmpty(qname.getPrefix())) { + + if (ObjectReferencePathSegment.QNAME.equals(qname)) { + sb.append(ObjectReferencePathSegment.SYMBOL); + } else if (ParentPathSegment.QNAME.equals(qname)) { + sb.append(ParentPathSegment.SYMBOL); + } else if (IdentifierPathSegment.QNAME.equals(qname)) { + sb.append(IdentifierPathSegment.SYMBOL); + } else if (!StringUtils.isEmpty(qname.getPrefix())) { sb.append(qname.getPrefix() + ":" + qname.getLocalPart()); } else { if (StringUtils.isNotEmpty(qname.getNamespaceURI())) { @@ -435,7 +456,7 @@ public ItemPath toItemPath() { } else { QName qName = segment.getQName(); boolean variable = segment.isVariable(); - segments.add(new NameItemPathSegment(qName, variable)); + segments.add(ItemPath.createSegment(qName, variable)); } } ItemPath path = new ItemPath(segments); diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/path/IdentifierPathSegment.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/path/IdentifierPathSegment.java index 46809c17912..6736f8dc432 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/path/IdentifierPathSegment.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/path/IdentifierPathSegment.java @@ -16,6 +16,10 @@ package com.evolveum.midpoint.prism.path; +import com.evolveum.midpoint.prism.PrismConstants; + +import javax.xml.namespace.QName; + /** * Denotes identifier of the object or container (i.e. OID or container ID). * Currently supported only for sorting (not even for filtering!). @@ -24,7 +28,10 @@ */ public class IdentifierPathSegment extends ItemPathSegment { - @Override + public static final String SYMBOL = "#"; + public static final QName QNAME = PrismConstants.T_ID; + + @Override public boolean equivalent(Object obj) { return equals(obj); } @@ -36,6 +43,6 @@ public ItemPathSegment clone() { @Override public String toString() { - return "#"; + return SYMBOL; } } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/path/ItemPath.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/path/ItemPath.java index d139f04feec..13818a6188a 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/path/ItemPath.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/path/ItemPath.java @@ -87,12 +87,12 @@ public ItemPath(Object[] namesOrIds) { private QName stringToQName(String name) { Validate.notNull(name, "name"); - if ("..".equals(name)) { - return PrismConstants.T_PARENT; - } else if ("@".equals(name)) { - return PrismConstants.T_OBJECT_REFERENCE; - } else if ("#".equals(name)) { - return PrismConstants.T_ID; + if (ParentPathSegment.SYMBOL.equals(name)) { + return ParentPathSegment.QNAME; + } else if (ObjectReferencePathSegment.SYMBOL.equals(name)) { + return ObjectReferencePathSegment.QNAME; + } else if (IdentifierPathSegment.SYMBOL.equals(name)) { + return IdentifierPathSegment.QNAME; } else { return new QName(name); } @@ -171,14 +171,18 @@ public static ItemPath subPath(ItemPath prefix, ItemPathSegment subSegment) { } private void add(QName qname) { - if (PrismConstants.T_PARENT.equals(qname)) { - this.segments.add(new ParentPathSegment()); - } else if (PrismConstants.T_OBJECT_REFERENCE.equals(qname)) { - this.segments.add(new ObjectReferencePathSegment()); - } else if (PrismConstants.T_ID.equals(qname)) { - this.segments.add(new IdentifierPathSegment()); + this.segments.add(createSegment(qname, false)); + } + + public static ItemPathSegment createSegment(QName qname, boolean variable) { + if (ParentPathSegment.QNAME.equals(qname)) { + return new ParentPathSegment(); + } else if (ObjectReferencePathSegment.QNAME.equals(qname)) { + return new ObjectReferencePathSegment(); + } else if (IdentifierPathSegment.QNAME.equals(qname)) { + return new IdentifierPathSegment(); } else { - this.segments.add(new NameItemPathSegment(qname)); + return new NameItemPathSegment(qname, variable); } } @@ -586,6 +590,14 @@ public int hashCode() { return result; } + public boolean equals(Object obj, boolean exact) { + if (exact) { + return equals(obj); + } else { + return obj instanceof ItemPath && equivalent((ItemPath) obj); + } + } + /** * More strict version of ItemPath comparison. Does not use any normalization * nor approximate matching QNames via QNameUtil.match. diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/path/ObjectReferencePathSegment.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/path/ObjectReferencePathSegment.java index 573f2e7f881..fff445d2fc5 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/path/ObjectReferencePathSegment.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/path/ObjectReferencePathSegment.java @@ -16,6 +16,10 @@ package com.evolveum.midpoint.prism.path; +import com.evolveum.midpoint.prism.PrismConstants; + +import javax.xml.namespace.QName; + /** * Denotes referenced object, like "assignment/targetRef/@/name" (name of assignment's target object) * @@ -23,7 +27,10 @@ */ public class ObjectReferencePathSegment extends ReferencePathSegment { - @Override + public static final String SYMBOL = "@"; + public static final QName QNAME = PrismConstants.T_OBJECT_REFERENCE; + + @Override public boolean equivalent(Object obj) { return equals(obj); } @@ -35,6 +42,6 @@ public ItemPathSegment clone() { @Override public String toString() { - return "@"; + return SYMBOL; } } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/path/ParentPathSegment.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/path/ParentPathSegment.java index 642ebdecf2f..73176ec731f 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/path/ParentPathSegment.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/path/ParentPathSegment.java @@ -16,6 +16,10 @@ package com.evolveum.midpoint.prism.path; +import com.evolveum.midpoint.prism.PrismConstants; + +import javax.xml.namespace.QName; + /** * Denotes parent object or container. * @@ -23,7 +27,10 @@ */ public class ParentPathSegment extends ReferencePathSegment { - @Override + public static final String SYMBOL = ".."; + public static final QName QNAME = PrismConstants.T_PARENT; + + @Override public boolean equivalent(Object obj) { return equals(obj); } @@ -35,6 +42,6 @@ public ItemPathSegment clone() { @Override public String toString() { - return ".."; + return SYMBOL; } } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/AllFilter.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/AllFilter.java index 2f1a4815579..91ab494d0dd 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/AllFilter.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/AllFilter.java @@ -74,4 +74,13 @@ public boolean match(PrismContainerValue value, MatchingRuleRegistry matchingRul return true; } + @Override + public boolean equals(Object obj, boolean exact) { + return obj instanceof AllFilter; + } + + @Override + public int hashCode() { + return 0; + } } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/AndFilter.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/AndFilter.java index 39022a794ae..641327bda3a 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/AndFilter.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/AndFilter.java @@ -106,4 +106,8 @@ public boolean match(PrismContainerValue value, MatchingRuleRegistry matchingRul return true; } + @Override + public boolean equals(Object obj, boolean exact) { + return super.equals(obj, exact) && obj instanceof AndFilter; + } } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ComparativeFilter.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ComparativeFilter.java index e32cde5be8b..b23aa70de19 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ComparativeFilter.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ComparativeFilter.java @@ -74,24 +74,24 @@ static PrismPropertyValue createPropertyValue(PrismPropertyDefinition ite } @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + (equals ? 1231 : 1237); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) + public boolean equals(Object o, boolean exact) { + if (this == o) return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) + if (o == null || getClass() != o.getClass()) return false; - ComparativeFilter other = (ComparativeFilter) obj; - if (equals != other.equals) + if (!super.equals(o, exact)) return false; - return true; + + ComparativeFilter that = (ComparativeFilter) o; + + return equals == that.equals; + + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + (equals ? 1 : 0); + return result; } } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/EqualFilter.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/EqualFilter.java index d32767f0d34..32955feecea 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/EqualFilter.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/EqualFilter.java @@ -96,6 +96,16 @@ public static EqualFilter createEqual(ItemPath path, PrismPropertyDefinit List> pVals = createPropertyList(itemDefinition, realValue); return new EqualFilter(path, itemDefinition, matchingRule, pVals); } + + public static EqualFilter createEqualMultiple(ItemPath path, PrismPropertyDefinition itemDefinition, QName matchingRule, T... realValues) { + Validate.notNull(itemDefinition, "Item definition in the filter must not be null"); + Validate.notNull(path, "Path in the filter must not be null"); + if (realValues.length == 0 || (realValues.length == 1 && realValues[0] == null)) { + return createNullEqual(path, itemDefinition, matchingRule); + } + List> pVals = createPropertyListFromArray(itemDefinition, realValues); + return new EqualFilter(path, itemDefinition, matchingRule, pVals); + } public static EqualFilter createEqual(QName propertyName, PrismPropertyDefinition propertyDefinition, QName matchingRule, T realValue){ return createEqual(new ItemPath(propertyName), propertyDefinition, matchingRule, realValue); @@ -280,6 +290,11 @@ public List> getValues() { // TODO Auto-generated method stub return super.getValues(); } - + + @Override + public boolean equals(Object obj, boolean exact) { + return super.equals(obj, exact) && obj instanceof EqualFilter; + } + } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ExistsFilter.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ExistsFilter.java index 92cd8e37a27..710ecf364bf 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ExistsFilter.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ExistsFilter.java @@ -124,28 +124,7 @@ public String debugDump(int indent) { return sb.toString(); } - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof ExistsFilter)) return false; - - ExistsFilter that = (ExistsFilter) o; - - if (fullPath != null ? !fullPath.equals(that.fullPath) : that.fullPath != null) return false; - if (definition != null ? !definition.equals(that.definition) : that.definition != null) return false; - return !(filter != null ? !filter.equals(that.filter) : that.filter != null); - - } - - @Override - public int hashCode() { - int result = fullPath != null ? fullPath.hashCode() : 0; - result = 31 * result + (definition != null ? definition.hashCode() : 0); - result = 31 * result + (filter != null ? filter.hashCode() : 0); - return result; - } - - @Override + @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append("EXISTS("); @@ -163,4 +142,30 @@ public void accept(Visitor visitor) { visitor.visit(filter); } } + + @Override + public boolean equals(Object o, boolean exact) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + + ExistsFilter that = (ExistsFilter) o; + + if (fullPath != null ? !fullPath.equals(that.fullPath, exact) : that.fullPath != null) + return false; + if (exact) { + if (definition != null ? !definition.equals(that.definition) : that.definition != null) + return false; + } + return filter != null ? filter.equals(that.filter, exact) : that.filter == null; + } + + @Override + public int hashCode() { + int result = 1; + result = 31 * result + (definition != null ? definition.hashCode() : 0); + result = 31 * result + (filter != null ? filter.hashCode() : 0); + return result; + } } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/GreaterFilter.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/GreaterFilter.java index d0e64885063..02c6c8d7dd0 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/GreaterFilter.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/GreaterFilter.java @@ -38,38 +38,38 @@ public class GreaterFilter extends ComparativeFilter { public GreaterFilter() { } - GreaterFilter(ItemPath parentPath, PrismPropertyDefinition definition, PrismPropertyValue value, boolean equals) { - super(parentPath, definition, value, equals); + GreaterFilter(ItemPath itemPath, PrismPropertyDefinition definition, PrismPropertyValue value, boolean equals) { + super(itemPath, definition, value, equals); } - GreaterFilter(ItemPath parentPath, PrismPropertyDefinition definition, ItemPath rightSidePath, ItemDefinition rightSideDefinition, boolean equals) { - super(parentPath, definition, rightSidePath, rightSideDefinition, equals); + GreaterFilter(ItemPath itemPath, PrismPropertyDefinition definition, ItemPath rightSidePath, ItemDefinition rightSideDefinition, boolean equals) { + super(itemPath, definition, rightSidePath, rightSideDefinition, equals); } - public static GreaterFilter createGreater(ItemPath parentPath, PrismPropertyDefinition definition, PrismPropertyValue value, boolean equals){ - return new GreaterFilter(parentPath, definition, value, equals); + public static GreaterFilter createGreater(ItemPath itemPath, PrismPropertyDefinition definition, PrismPropertyValue value, boolean equals){ + return new GreaterFilter(itemPath, definition, value, equals); } - public static GreaterFilter createGreater(ItemPath parentPath, PrismContainerDefinition containerDef, + public static GreaterFilter createGreater(ItemPath itemPath, PrismContainerDefinition containerDef, PrismPropertyValue value, boolean equals) throws SchemaException { - PrismPropertyDefinition def = (PrismPropertyDefinition) FilterUtils.findItemDefinition(parentPath, containerDef); - return createGreater(parentPath, def, value, equals); + PrismPropertyDefinition def = (PrismPropertyDefinition) FilterUtils.findItemDefinition(itemPath, containerDef); + return createGreater(itemPath, def, value, equals); } - public static GreaterFilter createGreater(ItemPath parentPath, PrismPropertyDefinition itemDefinition, T realValue, boolean equals) throws SchemaException{ + public static GreaterFilter createGreater(ItemPath itemPath, PrismPropertyDefinition itemDefinition, T realValue, boolean equals) throws SchemaException{ PrismPropertyValue value = createPropertyValue(itemDefinition, realValue); if (value == null){ //TODO: create null } - return createGreater(parentPath, itemDefinition, value, equals); + return createGreater(itemPath, itemDefinition, value, equals); } - public static GreaterFilter createGreater(ItemPath parentPath, PrismContainerDefinition containerDef, + public static GreaterFilter createGreater(ItemPath itemPath, PrismContainerDefinition containerDef, T realValue, boolean equals) throws SchemaException { - PrismPropertyDefinition def = (PrismPropertyDefinition) FilterUtils.findItemDefinition(parentPath, containerDef); - return createGreater(parentPath, def, realValue, equals); + PrismPropertyDefinition def = (PrismPropertyDefinition) FilterUtils.findItemDefinition(itemPath, containerDef); + return createGreater(itemPath, def, realValue, equals); } public static GreaterFilter createGreater(QName propertyName, Class type, PrismContext prismContext, T realValue, boolean equals) @@ -84,6 +84,10 @@ public static GreaterFilter createGreater(ItemPath pat return createGreater(path, def, realValue, equals); } + + public static GreaterFilter createGreater(ItemPath propertyPath, PrismPropertyDefinition propertyDefinition, ItemPath rightSidePath, ItemDefinition rightSideDefinition, boolean equals) { + return new GreaterFilter(propertyPath, propertyDefinition, rightSidePath, rightSideDefinition, equals); + } @Override public GreaterFilter clone() { @@ -140,4 +144,10 @@ public ItemPath getPath() { public static GreaterFilter createGreaterThanItem(ItemPath itemPath, PrismPropertyDefinition propertyDefinition, ItemPath rightSidePath, ItemDefinition rightSideDefinition, boolean equals) { return new GreaterFilter(itemPath, propertyDefinition, rightSidePath, rightSideDefinition, equals); } + + @Override + public boolean equals(Object obj, boolean exact) { + return super.equals(obj, exact) && obj instanceof GreaterFilter; + } + } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/InFilter.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/InFilter.java index fe8aa2e124d..4aa2217c8e4 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/InFilter.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/InFilter.java @@ -26,6 +26,7 @@ import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.util.DebugUtil; +@Deprecated // deprecated because of confusing name/semantics; see https://wiki.evolveum.com/display/midPoint/Query+API+Evolution public class InFilter extends PropertyValueFilter { InFilter(ItemPath path, PrismPropertyDefinition definition, QName matchingRule, List values ) { @@ -104,5 +105,9 @@ public PrismPropertyDefinition getDefinition() { return (PrismPropertyDefinition) super.getDefinition(); } + @Override + public boolean equals(Object obj, boolean exact) { + return super.equals(obj, exact) && obj instanceof InFilter; + } } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/InOidFilter.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/InOidFilter.java index 3a5f7eccfa3..75817db6348 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/InOidFilter.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/InOidFilter.java @@ -35,15 +35,20 @@ public class InOidFilter extends ObjectFilter { private ExpressionWrapper expression; private boolean considerOwner; // temporary hack (checks owner OID) - InOidFilter(boolean considerOwner, Collection oids) { + private InOidFilter(boolean considerOwner, Collection oids) { this.considerOwner = considerOwner; this.oids = oids; } - InOidFilter(ExpressionWrapper expression){ + private InOidFilter(boolean considerOwner, ExpressionWrapper expression){ + this.considerOwner = considerOwner; this.expression = expression; } - + + public static InOidFilter createInOid(boolean considerOwner, Collection oids){ + return new InOidFilter(considerOwner, oids); + } + public static InOidFilter createInOid(Collection oids){ return new InOidFilter(false, oids); } @@ -60,8 +65,8 @@ public static InOidFilter createOwnerHasOidIn(String... oids){ return new InOidFilter(true, Arrays.asList(oids)); } - public static InOidFilter createInOid(ExpressionWrapper expression){ - return new InOidFilter(expression); + public static InOidFilter createInOid(boolean considerOwner, ExpressionWrapper expression){ + return new InOidFilter(considerOwner, expression); } public Collection getOids() { @@ -183,28 +188,27 @@ public boolean match(PrismContainerValue value, MatchingRuleRegistry matchingRul } @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((oids == null) ? 0 : oids.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) + public boolean equals(Object o, boolean exact) { + if (this == o) return true; - if (obj == null) + if (o == null || getClass() != o.getClass()) return false; - if (getClass() != obj.getClass()) + + InOidFilter that = (InOidFilter) o; + + if (considerOwner != that.considerOwner) return false; - InOidFilter other = (InOidFilter) obj; - if (oids == null) { - if (other.oids != null) - return false; - } else if (!oids.equals(other.oids)) + if (oids != null ? !oids.equals(that.oids) : that.oids != null) return false; - return true; + return expression != null ? expression.equals(that.expression) : that.expression == null; + } + @Override + public int hashCode() { + int result = oids != null ? oids.hashCode() : 0; + result = 31 * result + (expression != null ? expression.hashCode() : 0); + result = 31 * result + (considerOwner ? 1 : 0); + return result; + } } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/LessFilter.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/LessFilter.java index 6e6ae02cde2..04eebf4ead9 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/LessFilter.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/LessFilter.java @@ -24,7 +24,6 @@ import com.evolveum.midpoint.prism.PrismContainerDefinition; import com.evolveum.midpoint.prism.PrismContainerValue; import com.evolveum.midpoint.prism.PrismContext; -import com.evolveum.midpoint.prism.PrismObjectDefinition; import com.evolveum.midpoint.prism.PrismPropertyDefinition; import com.evolveum.midpoint.prism.PrismPropertyValue; import com.evolveum.midpoint.prism.match.MatchingRuleRegistry; @@ -34,55 +33,55 @@ public class LessFilter extends ComparativeFilter { - LessFilter(ItemPath parentPath, PrismPropertyDefinition definition, PrismPropertyValue value, boolean equals) { - super(parentPath, definition, value, equals); + LessFilter(ItemPath itemPath, PrismPropertyDefinition definition, PrismPropertyValue value, boolean equals) { + super(itemPath, definition, value, equals); } - LessFilter(ItemPath parentPath, PrismPropertyDefinition definition, ItemPath rightSidePath, ItemDefinition rightSideDefinition, boolean equals) { - super(parentPath, definition, rightSidePath, rightSideDefinition, equals); + LessFilter(ItemPath itemPath, PrismPropertyDefinition definition, ItemPath rightSidePath, ItemDefinition rightSideDefinition, boolean equals) { + super(itemPath, definition, rightSidePath, rightSideDefinition, equals); } public LessFilter() { } - public static LessFilter createLess(QName parentPath, PrismPropertyDefinition definition, PrismPropertyValue value, boolean equals){ - return new LessFilter(new ItemPath(parentPath), definition, value, equals); + public static LessFilter createLess(QName itemPath, PrismPropertyDefinition definition, PrismPropertyValue value, boolean equals){ + return new LessFilter(new ItemPath(itemPath), definition, value, equals); } - public static LessFilter createLess(ItemPath parentPath, PrismPropertyDefinition definition, PrismPropertyValue value, boolean equals){ - return new LessFilter(parentPath, definition, value, equals); + public static LessFilter createLess(ItemPath itemPath, PrismPropertyDefinition definition, PrismPropertyValue value, boolean equals){ + return new LessFilter(itemPath, definition, value, equals); } - public static LessFilter createLess(ItemPath parentPath, PrismContainerDefinition containerDef, + public static LessFilter createLess(ItemPath itemPath, PrismContainerDefinition containerDef, PrismPropertyValue value, boolean equals) throws SchemaException { - PrismPropertyDefinition def = (PrismPropertyDefinition) FilterUtils.findItemDefinition(parentPath, containerDef); - return createLess(parentPath, def, value, equals); + PrismPropertyDefinition def = (PrismPropertyDefinition) FilterUtils.findItemDefinition(itemPath, containerDef); + return createLess(itemPath, def, value, equals); } - public static LessFilter createLess(QName parentPath, PrismPropertyDefinition itemDefinition, T realValue, boolean equals) throws SchemaException{ - return createLess(new ItemPath(parentPath), itemDefinition, realValue, equals); + public static LessFilter createLess(QName itemPath, PrismPropertyDefinition itemDefinition, T realValue, boolean equals) throws SchemaException{ + return createLess(new ItemPath(itemPath), itemDefinition, realValue, equals); } - public static LessFilter createLess(ItemPath parentPath, PrismPropertyDefinition itemDefinition, T realValue, boolean equals) throws SchemaException{ + public static LessFilter createLess(ItemPath itemPath, PrismPropertyDefinition itemDefinition, T realValue, boolean equals) throws SchemaException{ PrismPropertyValue value = createPropertyValue(itemDefinition, realValue); if (value == null){ // create null filter } - return createLess(parentPath, itemDefinition, value, equals); + return createLess(itemPath, itemDefinition, value, equals); } public static LessFilter createLessThanItem(ItemPath itemPath, PrismPropertyDefinition propertyDefinition, ItemPath rightSidePath, ItemDefinition rightSideDefinition, boolean equals) { return new LessFilter(itemPath, propertyDefinition, rightSidePath, rightSideDefinition, equals); } - public static LessFilter createLess(ItemPath parentPath, PrismContainerDefinition containerDef, + public static LessFilter createLess(ItemPath itemPath, PrismContainerDefinition containerDef, T realValue, boolean equals) throws SchemaException { - PrismPropertyDefinition def = (PrismPropertyDefinition) FilterUtils.findItemDefinition(parentPath, containerDef); - return createLess(parentPath, def, realValue, equals); + PrismPropertyDefinition def = (PrismPropertyDefinition) FilterUtils.findItemDefinition(itemPath, containerDef); + return createLess(itemPath, def, realValue, equals); } public static LessFilter createLess(QName propertyName, Class type, PrismContext prismContext, T realValue, boolean equals) @@ -96,7 +95,12 @@ public static LessFilter createLess(ItemPath path, Cla PrismPropertyDefinition def = (PrismPropertyDefinition) FilterUtils.findItemDefinition(path, type, prismContext); return createLess(path, def, realValue, equals); - } + } + + public static LessFilter createLess(ItemPath propertyPath, PrismPropertyDefinition propertyDefinition, ItemPath rightSidePath, ItemDefinition rightSideDefinition, boolean equals) { + return new LessFilter(propertyPath, propertyDefinition, rightSidePath, rightSideDefinition, equals); + } + @Override public LessFilter clone() { LessFilter clone = new LessFilter(getFullPath(), getDefinition(), getSingleValue(), isEquals()); @@ -149,4 +153,10 @@ public ItemPath getPath() { return getFullPath(); } + @Override + public boolean equals(Object obj, boolean exact) { + return super.equals(obj, exact) && obj instanceof LessFilter; + } + + } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/LogicalFilter.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/LogicalFilter.java index d376996ab90..64fb4e82726 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/LogicalFilter.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/LogicalFilter.java @@ -99,7 +99,7 @@ public int hashCode() { } @Override - public boolean equals(Object obj) { + public boolean equals(Object obj, boolean exact) { if (this == obj) return true; if (obj == null) @@ -107,11 +107,19 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; LogicalFilter other = (LogicalFilter) obj; - if (conditions == null) { - if (other.conditions != null) + + if (conditions != null) { + if (conditions.size() != other.conditions.size()) { return false; - } else if (!conditions.equals(other.conditions)) - return false; + } + for (int i = 0; i < conditions.size(); i++) { + ObjectFilter of1 = this.conditions.get(i); + ObjectFilter of2 = other.conditions.get(i); + if (!of1.equals(of2, exact)) { + return false; + } + } + } return true; } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/NoneFilter.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/NoneFilter.java index 62104cedce8..083e6b03bbe 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/NoneFilter.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/NoneFilter.java @@ -73,4 +73,15 @@ public String toString() { public boolean match(PrismContainerValue value, MatchingRuleRegistry matchingRuleRegistry) throws SchemaException { return false; } + + @Override + public boolean equals(Object obj, boolean exact) { + return obj instanceof NoneFilter; + } + + @Override + public int hashCode() { + return 0; + } + } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/NotFilter.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/NotFilter.java index 5b1b51a174c..77321630c4f 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/NotFilter.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/NotFilter.java @@ -90,4 +90,10 @@ public String toString() { public boolean match(PrismContainerValue value, MatchingRuleRegistry matchingRuleRegistry) throws SchemaException { return !getFilter().match(value, matchingRuleRegistry); } + + @Override + public boolean equals(Object obj, boolean exact) { + return super.equals(obj, exact) && obj instanceof NotFilter; + } + } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ObjectFilter.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ObjectFilter.java index d6b73902d99..f7994a4ce97 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ObjectFilter.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ObjectFilter.java @@ -52,4 +52,6 @@ public void revive(final PrismContext prismContext) throws SchemaException { } public abstract void checkConsistence(); + + public abstract boolean equals(Object o, boolean exact); } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ObjectOrdering.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ObjectOrdering.java index a22b26b266f..fa26e32b2aa 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ObjectOrdering.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ObjectOrdering.java @@ -52,4 +52,30 @@ public OrderDirection getDirection() { public String toString() { return orderBy.toString() + " " + direction; } + + @Override + public boolean equals(Object o) { + return equals(o, true); + } + + public boolean equals(Object o, boolean exact) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + + ObjectOrdering that = (ObjectOrdering) o; + + if (orderBy != null ? !orderBy.equals(that.orderBy, exact) : that.orderBy != null) + return false; + return direction == that.direction; + + } + + @Override + public int hashCode() { + int result = 1; + result = 31 * result + (direction != null ? direction.hashCode() : 0); + return result; + } } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ObjectPaging.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ObjectPaging.java index 4708c9dc1c2..e48bb8b14e0 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ObjectPaging.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ObjectPaging.java @@ -256,4 +256,48 @@ public String toString() { return sb.toString(); } + + @Override + public boolean equals(Object o) { + return equals(o, true); + } + + public boolean equals(Object o, boolean exact) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + + ObjectPaging that = (ObjectPaging) o; + + if (offset != null ? !offset.equals(that.offset) : that.offset != null) + return false; + if (maxSize != null ? !maxSize.equals(that.maxSize) : that.maxSize != null) + return false; + if ((ordering != null && that.ordering == null) || (ordering == null && that.ordering != null)) { + return false; + } + if (ordering != null) { + if (ordering.size() != that.ordering.size()) { + return false; + } + for (int i = 0; i < ordering.size(); i++) { + ObjectOrdering oo1 = this.ordering.get(i); + ObjectOrdering oo2 = that.ordering.get(i); + if (!oo1.equals(oo2, exact)) { + return false; + } + } + } + return cookie != null ? cookie.equals(that.cookie) : that.cookie == null; + } + + @Override + public int hashCode() { + int result = offset != null ? offset.hashCode() : 0; + result = 31 * result + (maxSize != null ? maxSize.hashCode() : 0); + result = 31 * result + (ordering != null ? ordering.hashCode() : 0); + result = 31 * result + (cookie != null ? cookie.hashCode() : 0); + return result; + } } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ObjectQuery.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ObjectQuery.java index 21a61e23048..f5cde569b33 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ObjectQuery.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ObjectQuery.java @@ -208,4 +208,39 @@ public Integer getMaxSize() { } return paging.getMaxSize(); } + + public boolean equals(Object o) { + return equals(o, true); + } + + public boolean equivalent(Object o) { + return equals(o, false); + } + + public boolean equals(Object o, boolean exact) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + + ObjectQuery that = (ObjectQuery) o; + + if (allowPartialResults != that.allowPartialResults) + return false; + if (useNewQueryInterpreter != that.useNewQueryInterpreter) + return false; + if (filter != null ? !filter.equals(that.filter, exact) : that.filter != null) + return false; + return paging != null ? paging.equals(that.paging, exact) : that.paging == null; + + } + + @Override + public int hashCode() { + int result = filter != null ? filter.hashCode() : 0; + result = 31 * result + (paging != null ? paging.hashCode() : 0); + result = 31 * result + (allowPartialResults ? 1 : 0); + result = 31 * result + (useNewQueryInterpreter ? 1 : 0); + return result; + } } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/OrFilter.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/OrFilter.java index 71edf0c1efe..137a40cda76 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/OrFilter.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/OrFilter.java @@ -99,4 +99,10 @@ public boolean match(PrismContainerValue value, MatchingRuleRegistry matchingRul } return false; } + + @Override + public boolean equals(Object obj, boolean exact) { + return super.equals(obj, exact) && obj instanceof OrFilter; + } + } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/OrgFilter.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/OrgFilter.java index 7aced926976..cf38b456800 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/OrgFilter.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/OrgFilter.java @@ -27,7 +27,7 @@ public class OrgFilter extends ObjectFilter { - public static enum Scope {ONE_LEVEL, SUBTREE} + public enum Scope {ONE_LEVEL, SUBTREE} private PrismReferenceValue baseOrgRef; private Scope scope; @@ -113,7 +113,7 @@ public int hashCode() { } @Override - public boolean equals(Object obj) { + public boolean equals(Object obj, boolean exact) { if (this == obj) return true; if (obj == null) diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/PropertyValueFilter.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/PropertyValueFilter.java index 7c4f99b05b7..52f4babaeaf 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/PropertyValueFilter.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/PropertyValueFilter.java @@ -17,7 +17,6 @@ package com.evolveum.midpoint.prism.query; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.List; @@ -25,40 +24,26 @@ import com.evolveum.midpoint.prism.PrismContainerValue; -import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.Validate; -import org.w3c.dom.Element; -import com.evolveum.midpoint.prism.Containerable; import com.evolveum.midpoint.prism.Item; import com.evolveum.midpoint.prism.ItemDefinition; import com.evolveum.midpoint.prism.Itemable; -import com.evolveum.midpoint.prism.Objectable; -import com.evolveum.midpoint.prism.PrismConstants; -import com.evolveum.midpoint.prism.PrismContainerDefinition; -import com.evolveum.midpoint.prism.PrismContext; -import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.PrismObjectDefinition; import com.evolveum.midpoint.prism.PrismPropertyDefinition; import com.evolveum.midpoint.prism.PrismPropertyValue; import com.evolveum.midpoint.prism.PrismValue; -import com.evolveum.midpoint.prism.match.MatchingRule; import com.evolveum.midpoint.prism.match.MatchingRuleRegistry; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.util.PrismUtil; -import com.evolveum.midpoint.prism.xnode.MapXNode; -import com.evolveum.midpoint.prism.xnode.XNode; import com.evolveum.midpoint.util.DebugUtil; import com.evolveum.midpoint.util.exception.SchemaException; -import com.evolveum.midpoint.util.exception.SystemException; -import com.evolveum.prism.xml.ns._public.types_3.PolyStringType; public abstract class PropertyValueFilter extends ValueFilter implements Itemable { private ExpressionWrapper expression; private List values; - private ItemPath rightSidePath; // alternative to "values" - private ItemDefinition rightSideDefinition; // optional (needed only if path points to extension item) + private ItemPath rightHandSidePath; // alternative to "values" + private ItemDefinition rightHandSideDefinition; // optional (needed only if path points to extension item) /* * TODO clean up the right side path/definition mess @@ -68,11 +53,11 @@ public abstract class PropertyValueFilter extends ValueFil super(); } - PropertyValueFilter(ItemPath path, ItemDefinition definition, QName matchingRule, ItemPath rightSidePath, ItemDefinition rightSideDefinition) { + PropertyValueFilter(ItemPath path, ItemDefinition definition, QName matchingRule, ItemPath rightHandSidePath, ItemDefinition rightHandSideDefinition) { super(path, definition, matchingRule); - Validate.notNull(rightSidePath, "rightSidePath"); - this.rightSidePath = rightSidePath; - this.rightSideDefinition = rightSideDefinition; + Validate.notNull(rightHandSidePath, "rightHandSidePath"); + this.rightHandSidePath = rightHandSidePath; + this.rightHandSideDefinition = rightHandSideDefinition; } PropertyValueFilter(ItemPath path, ItemDefinition definition, QName matchingRule, List values) { @@ -127,7 +112,22 @@ static List> createPropertyList(PrismPropertyDefinitio return pValues; } - + + static List> createPropertyListFromArray(PrismPropertyDefinition itemDefinition, T... realValues) { + List> pVals = new ArrayList>(); + + for (T realValue : realValues) { + if (realValue instanceof PrismPropertyValue) { + PrismPropertyValue pVal = (PrismPropertyValue) realValue; + PrismUtil.recomputePrismPropertyValue(pVal, itemDefinition.getPrismContext()); + pVals.add(pVal); + } else { + pVals.add(new PrismPropertyValue<>(realValue)); + } + } + return pVals; + } + static List> createPropertyList(PrismPropertyDefinition itemDefinition, T realValue){ List> pVals = new ArrayList>(); @@ -138,6 +138,7 @@ static List> createPropertyList(PrismPropertyDefinitio PrismUtil.recomputePrismPropertyValue(pVal, itemDefinition.getPrismContext()); pVals.add(pVal); }else{ + // TODO what's this??? pVals.addAll(PrismPropertyValue.createCollection((Collection) realValue)); } } @@ -214,23 +215,23 @@ public Item getFilterItem() throws SchemaException{ return filterItem; } - public ItemPath getRightSidePath() { - return rightSidePath; + public ItemPath getRightHandSidePath() { + return rightHandSidePath; } - public ItemDefinition getRightSideDefinition() { - return rightSideDefinition; + public ItemDefinition getRightHandSideDefinition() { + return rightHandSideDefinition; } - public void setRightSidePath(ItemPath rightSidePath) { - this.rightSidePath = rightSidePath; - if (rightSidePath != null) { + public void setRightHandSidePath(ItemPath rightHandSidePath) { + this.rightHandSidePath = rightHandSidePath; + if (rightHandSidePath != null) { values = null; } } - public void setRightSideDefinition(ItemDefinition rightSideDefinition) { - this.rightSideDefinition = rightSideDefinition; + public void setRightHandSideDefinition(ItemDefinition rightHandSideDefinition) { + this.rightHandSideDefinition = rightHandSideDefinition; } public ExpressionWrapper getExpression() { @@ -286,36 +287,46 @@ public boolean match(PrismContainerValue cvalue, MatchingRuleRegistry matchingRu return true; } - + @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((expression == null) ? 0 : expression.hashCode()); - result = prime * result + ((values == null) ? 0 : values.hashCode()); - return result; + public boolean equals(Object o) { + return equals(o, true); } @Override - public boolean equals(Object obj) { - if (this == obj) + public boolean equals(Object o, boolean exact) { + if (this == o) return true; - if (obj == null) + if (o == null || getClass() != o.getClass()) return false; - if (getClass() != obj.getClass()) + if (!super.equals(o, exact)) return false; - PropertyValueFilter other = (PropertyValueFilter) obj; - if (expression == null) { - if (other.expression != null) - return false; - } else if (!expression.equals(other.expression)) + + PropertyValueFilter that = (PropertyValueFilter) o; + + if (expression != null ? !expression.equals(that.expression) : that.expression != null) return false; - if (values == null) { - if (other.values != null) - return false; - } else if (!values.equals(other.values)) + if (values != null ? !values.equals(that.values) : that.values != null) return false; - return true; + if (rightHandSidePath != null ? !rightHandSidePath.equals(that.rightHandSidePath, exact) : that.rightHandSidePath != null) + return false; + if (exact) { + return rightHandSideDefinition != null ? + rightHandSideDefinition.equals(that.rightHandSideDefinition) : + that.rightHandSideDefinition == null; + } else { + return true; + } + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + (expression != null ? expression.hashCode() : 0); + result = 31 * result + (values != null ? values.hashCode() : 0); + result = 31 * result + (rightHandSidePath != null ? rightHandSidePath.hashCode() : 0); + result = 31 * result + (rightHandSideDefinition != null ? rightHandSideDefinition.hashCode() : 0); + return result; } public String debugDump(int indent, StringBuilder sb){ @@ -355,7 +366,7 @@ public String debugDump(int indent, StringBuilder sb){ sb.append(DebugUtil.debugDump(expression.getExpression(), indent + 2)); } - if (getRightSidePath() != null) { + if (getRightHandSidePath() != null) { sb.append("\n"); DebugUtil.indentDebugDump(sb, indent+1); sb.append("RIGHT SIDE PATH: "); @@ -363,8 +374,8 @@ public String debugDump(int indent, StringBuilder sb){ sb.append("\n"); DebugUtil.indentDebugDump(sb, indent+1); sb.append("RIGHT SIDE DEF: "); - if (getRightSideDefinition() != null) { - sb.append(getRightSideDefinition().toString()); + if (getRightHandSideDefinition() != null) { + sb.append(getRightHandSideDefinition().toString()); } else { sb.append("null"); } @@ -399,8 +410,8 @@ public String toString(StringBuilder sb){ } } } - if (rightSidePath != null) { - sb.append(getRightSidePath()); + if (rightHandSidePath != null) { + sb.append(getRightHandSidePath()); } return sb.toString(); } @@ -410,11 +421,11 @@ public String toString(StringBuilder sb){ public abstract PropertyValueFilter clone(); protected void copyRightSideThingsFrom(PropertyValueFilter original) { - if (original.getRightSidePath() != null) { - setRightSidePath(original.getRightSidePath()); + if (original.getRightHandSidePath() != null) { + setRightHandSidePath(original.getRightHandSidePath()); } - if (original.getRightSideDefinition() != null) { - setRightSideDefinition(original.getRightSideDefinition()); + if (original.getRightHandSideDefinition() != null) { + setRightHandSideDefinition(original.getRightHandSideDefinition()); } } } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/QueryJaxbConvertor.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/QueryJaxbConvertor.java index 6cf3a29bf9b..4953ae4df06 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/QueryJaxbConvertor.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/QueryJaxbConvertor.java @@ -18,16 +18,10 @@ import javax.xml.namespace.QName; -import org.w3c.dom.Element; - -import com.evolveum.midpoint.prism.Objectable; -import com.evolveum.midpoint.prism.PrismContext; -import com.evolveum.midpoint.prism.PrismObjectDefinition; +import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.prism.parser.QueryConvertor; import com.evolveum.midpoint.prism.xnode.MapXNode; -import com.evolveum.midpoint.prism.xnode.XNode; import com.evolveum.midpoint.util.DOMUtil; -import com.evolveum.midpoint.util.QNameUtil; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.prism.xml.ns._public.query_3.PagingType; import com.evolveum.prism.xml.ns._public.query_3.QueryType; @@ -54,7 +48,7 @@ public static ObjectQuery createTypeObjectQuery(QueryType queryType, PrismContex if (queryType.getFilter().containsFilterClause()){ MapXNode mapXnode = queryType.getFilter().getFilterClauseXNode(); - QName type = mapXnode.getParsedPrimitiveValue(QueryConvertor.KEY_FILTER_TYPE_TYPE, DOMUtil.XSD_QNAME); + QName type = mapXnode.getParsedPrimitiveValue(QueryConvertor.ELEMENT_TYPE, DOMUtil.XSD_QNAME); if (type == null){ throw new SchemaException("Query does not countain type filter. Cannot by parse."); } @@ -110,16 +104,16 @@ public static ObjectFilter createObjectFilter(PrismObject } } - public static ObjectQuery createObjectQueryInternal(Class clazz, SearchFilterType filterType, PagingType pagingType, PrismContext prismContext) + public static ObjectQuery createObjectQueryInternal(Class clazz, SearchFilterType filterType, PagingType pagingType, PrismContext prismContext) throws SchemaException { - PrismObjectDefinition objDef = prismContext.getSchemaRegistry().findObjectDefinitionByCompileTimeClass(clazz); + PrismContainerDefinition objDef = prismContext.getSchemaRegistry().findContainerDefinitionByCompileTimeClass(clazz); if (objDef == null) { - throw new SchemaException("cannot find obj definition for class "+clazz); + throw new SchemaException("cannot find obj/container definition for class "+clazz); } return createObjectQueryInternal(objDef, filterType, pagingType, prismContext); } - public static ObjectQuery createObjectQueryInternal(PrismObjectDefinition objDef, SearchFilterType filterType, PagingType pagingType, PrismContext prismContext) + public static ObjectQuery createObjectQueryInternal(PrismContainerDefinition objDef, SearchFilterType filterType, PagingType pagingType, PrismContext prismContext) throws SchemaException { try { diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/RefFilter.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/RefFilter.java index 97e89fdf43e..1e3b0ba865b 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/RefFilter.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/RefFilter.java @@ -237,4 +237,10 @@ public PrismReferenceDefinition getDefinition() { // TODO Auto-generated method stub return (PrismReferenceDefinition) super.getDefinition(); } + + @Override + public boolean equals(Object obj, boolean exact) { + return super.equals(obj, exact) && obj instanceof RefFilter; + } + } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/SubstringFilter.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/SubstringFilter.java index e6a7612e47d..eddc75caef9 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/SubstringFilter.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/SubstringFilter.java @@ -124,7 +124,7 @@ public static SubstringFilter createSubstring(ItemPath path, PrismPropertyDe return createNullSubstring(path, itemDefinition, matchingRule); } List> pValues = createPropertyList(itemDefinition, realValues); - return new SubstringFilter(path, itemDefinition, matchingRule, pValues); + return new SubstringFilter(path, itemDefinition, matchingRule, pValues, anchorStart, anchorEnd); } public static SubstringFilter createSubstring(ItemPath path, PrismPropertyDefinition itemDefinition, QName matchingRule, PrismPropertyValue values) { @@ -236,7 +236,14 @@ public String debugDump(int indent) { public String toString() { StringBuilder sb = new StringBuilder(); sb.append("SUBSTRING: "); - return toString(sb); + String rv = toString(sb); + if (anchorStart) { + rv += ",S"; + } + if (anchorEnd) { + rv += ",E"; + } + return rv; } @Override @@ -297,4 +304,28 @@ public PrismPropertyDefinition getDefinition() { return (PrismPropertyDefinition) super.getDefinition(); } + @Override + public boolean equals(Object o, boolean exact) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + if (!super.equals(o, exact)) + return false; + + SubstringFilter that = (SubstringFilter) o; + + if (anchorStart != that.anchorStart) + return false; + return anchorEnd == that.anchorEnd; + + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + (anchorStart ? 1 : 0); + result = 31 * result + (anchorEnd ? 1 : 0); + return result; + } } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/TypeFilter.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/TypeFilter.java index ffa49c6b496..959949b5eda 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/TypeFilter.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/TypeFilter.java @@ -124,13 +124,14 @@ public String debugDump(int indent) { } @Override - public boolean equals(Object o) { + public boolean equals(Object o, boolean exact) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; TypeFilter that = (TypeFilter) o; if (type != null ? !type.equals(that.type) : that.type != null) return false; + if (filter != null ? !filter.equals(that.filter, exact) : that.filter != null) return false; return true; } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/UndefinedFilter.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/UndefinedFilter.java index 3cbffdc1532..29ef92a6701 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/UndefinedFilter.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/UndefinedFilter.java @@ -49,4 +49,15 @@ public boolean match(PrismContainerValue value, MatchingRuleRegistry matchingRul return true; } + @Override + public boolean equals(Object obj, boolean exact) { + return obj instanceof UndefinedFilter; + } + + @Override + public int hashCode() { + return 0; + } + + } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ValueFilter.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ValueFilter.java index b3ebd1c9ab5..d2f53710a5f 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ValueFilter.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ValueFilter.java @@ -149,7 +149,7 @@ public int hashCode() { } @Override - public boolean equals(Object obj) { + public boolean equals(Object obj, boolean exact) { if (this == obj) return true; if (obj == null) @@ -157,15 +157,17 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; ValueFilter other = (ValueFilter) obj; - if (definition == null) { - if (other.definition != null) + if (exact) { + if (definition == null) { + if (other.definition != null) + return false; + } else if (!definition.equals(other.definition)) return false; - } else if (!definition.equals(other.definition)) - return false; + } if (fullPath == null) { if (other.fullPath != null) return false; - } else if (!fullPath.equivalent(other.fullPath)) // TODO: ok? + } else if (!fullPath.equals(other.fullPath, exact)) return false; if (matchingRule == null) { if (other.matchingRule != null) diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/builder/R_AtomicFilter.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/builder/R_AtomicFilter.java index e1146eab0e7..ba778c7ae03 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/builder/R_AtomicFilter.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/builder/R_AtomicFilter.java @@ -104,14 +104,14 @@ public S_AtomicFilterExit item(ItemPath itemPath, ItemDefinition itemDefinition) throw new IllegalStateException("item() call with no filter"); } PropertyValueFilter newFilter = filter.clone(); - newFilter.setRightSidePath(itemPath); - newFilter.setRightSideDefinition(itemDefinition); + newFilter.setRightHandSidePath(itemPath); + newFilter.setRightHandSideDefinition(itemDefinition); return new R_AtomicFilter(this, newFilter); } @Override - public S_MatchingRuleEntry eq(Object value) { - return new R_AtomicFilter(this, EqualFilter.createEqual(itemPath, propertyDefinition, null, value)); + public S_MatchingRuleEntry eq(Object... values) { + return new R_AtomicFilter(this, EqualFilter.createEqualMultiple(itemPath, propertyDefinition, null, values)); } @Override @@ -165,21 +165,36 @@ public S_RightHandItemEntry le() { } @Override - public S_MatchingRuleEntry startsWith(String value) { + public S_MatchingRuleEntry startsWith(Object value) { return new R_AtomicFilter(this, SubstringFilter.createSubstring(itemPath, propertyDefinition, null, value, true, false)); } - @Override - public S_MatchingRuleEntry endsWith(String value) { + @Override + public S_MatchingRuleEntry startsWithPoly(String orig, String norm) { + return startsWith(new PolyString(orig, norm)); + } + + @Override + public S_MatchingRuleEntry endsWith(Object value) { return new R_AtomicFilter(this, SubstringFilter.createSubstring(itemPath, propertyDefinition, null, value, false, true)); } + @Override + public S_MatchingRuleEntry endsWithPoly(String orig, String norm) { + return endsWith(new PolyString(orig, norm)); + } + @Override - public S_MatchingRuleEntry contains(String value) { + public S_MatchingRuleEntry contains(Object value) { return new R_AtomicFilter(this, SubstringFilter.createSubstring(itemPath, propertyDefinition, null, value, false, false)); } - @Override + @Override + public S_MatchingRuleEntry containsPoly(String orig, String norm) { + return contains(new PolyString(orig, norm)); + } + + @Override public S_AtomicFilterExit ref(PrismReferenceValue value) { return new R_AtomicFilter(this, RefFilter.createReferenceEqual(itemPath, referenceDefinition, value)); } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/builder/S_ConditionEntry.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/builder/S_ConditionEntry.java index 0ed9150e5dd..c71cb71d37e 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/builder/S_ConditionEntry.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/builder/S_ConditionEntry.java @@ -26,7 +26,7 @@ * @author mederly */ public interface S_ConditionEntry { - S_MatchingRuleEntry eq(Object value); + S_MatchingRuleEntry eq(Object... values); S_RightHandItemEntry eq(); S_MatchingRuleEntry eqPoly(String orig, String norm); S_MatchingRuleEntry gt(Object value) throws SchemaException; @@ -37,9 +37,12 @@ public interface S_ConditionEntry { S_RightHandItemEntry lt(); S_MatchingRuleEntry le(Object value) throws SchemaException; S_RightHandItemEntry le(); - S_AtomicFilterExit startsWith(String value); - S_AtomicFilterExit endsWith(String value); - S_AtomicFilterExit contains(String value); + S_MatchingRuleEntry startsWith(Object value); + S_MatchingRuleEntry startsWithPoly(String orig, String norm); + S_MatchingRuleEntry endsWith(Object value); + S_MatchingRuleEntry endsWithPoly(String orig, String norm); + S_MatchingRuleEntry contains(Object value); + S_MatchingRuleEntry containsPoly(String orig, String norm); S_AtomicFilterExit ref(PrismReferenceValue value); S_AtomicFilterExit ref(Collection values); // not supported by repo QueryInterpreter yet S_AtomicFilterExit ref(String oid); diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/schema/SchemaRegistry.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/schema/SchemaRegistry.java index e9c80e19aaa..204a2d34f28 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/schema/SchemaRegistry.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/schema/SchemaRegistry.java @@ -46,6 +46,7 @@ import org.apache.xml.resolver.Catalog; import org.apache.xml.resolver.CatalogManager; import org.apache.xml.resolver.tools.CatalogResolver; +import org.jetbrains.annotations.NotNull; import org.springframework.beans.factory.annotation.Autowired; import org.w3c.dom.Element; import org.w3c.dom.Node; @@ -656,14 +657,42 @@ public QName qualifyTypeName(QName typeName) throws SchemaException { return resolveUnqualifiedTypeName(typeName); } - public ComplexTypeDefinition determineParentDefinition(ComplexTypeDefinition complexTypeDefinition, ItemPath rest) { - ComplexTypeDefinition def = findComplexTypeDefinition(new QName( - "http://midpoint.evolveum.com/xml/ns/public/common/common-3", - "ObjectType")); // FIXME BRUTAL HACK - if (def == null) { - throw new IllegalStateException("Couldn't find definition for parent for " + complexTypeDefinition.getTypeName() + ", path=" + rest); + // current implementation tries to find all references to the child CTD and select those that are able to resolve path of 'rest' + // fails on ambiguity + // it's a bit fragile, as adding new references to child CTD in future may break existing code + public ComplexTypeDefinition determineParentDefinition(@NotNull ComplexTypeDefinition child, @NotNull ItemPath rest) { + ComplexTypeDefinition parent = null; + for (PrismSchema schema : getSchemas()) { + if (schema == null) { + continue; + } + for (ComplexTypeDefinition ctd : schema.getComplexTypeDefinitions()) { + for (ItemDefinition item : ctd.getDefinitions()) { + if (item instanceof PrismContainerDefinition) { + PrismContainerDefinition itemPcd = (PrismContainerDefinition) item; + if (itemPcd.getComplexTypeDefinition() != null) { + if (child.getTypeName().equals(itemPcd.getComplexTypeDefinition().getTypeName())) { + if (!rest.isEmpty() && ctd.findItemDefinition(rest) == null) { + continue; + } + if (parent != null && !parent.getTypeClass().equals(ctd.getTypeName())) { + throw new IllegalStateException("Couldn't find parent definition for " + child.getTypeName() + ": More than one candidate found: " + + parent.getTypeName() + ", " + itemPcd.getTypeName()); + } + parent = ctd; + } + } + } + } + } } - return def; +// ComplexTypeDefinition def = findComplexTypeDefinition(new QName( +// "http://midpoint.evolveum.com/xml/ns/public/common/common-3", +// "ObjectType")); // FIXME BRUTAL HACK + if (parent == null) { + throw new IllegalStateException("Couldn't find definition for parent for " + child.getTypeName() + ", path=" + rest); + } + return parent; } public PrismObjectDefinition determineReferencedObjectDefinition(QName targetTypeName, ItemPath rest) { diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/util/PrismTestUtil.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/util/PrismTestUtil.java index 75847db5fd8..5fce52527af 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/util/PrismTestUtil.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/util/PrismTestUtil.java @@ -224,6 +224,16 @@ public static void displayQuery(ObjectQuery query) { } } + public static void displayQueryXml(String xml) { + LOGGER.trace("object query XML:\n{}", xml); + System.out.println("object query XML:\n" + xml); + } + + public static void displayText(String text) { + LOGGER.trace(text); + System.out.println(text); + } + public static void displayQueryType(QueryType queryType) throws SchemaException { displaySearchFilterType(queryType.getFilter()); } diff --git a/infra/prism/src/main/java/com/evolveum/prism/xml/ns/_public/types_3/ObjectReferenceType.java b/infra/prism/src/main/java/com/evolveum/prism/xml/ns/_public/types_3/ObjectReferenceType.java index 19ddcbac74f..6f5a51631d2 100644 --- a/infra/prism/src/main/java/com/evolveum/prism/xml/ns/_public/types_3/ObjectReferenceType.java +++ b/infra/prism/src/main/java/com/evolveum/prism/xml/ns/_public/types_3/ObjectReferenceType.java @@ -41,40 +41,8 @@ /** - * - * Reference to an object. It contains OID of the object that it refers to. - * - * - *

Java class for ObjectReferenceType complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType name="ObjectReferenceType">
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <sequence>
- *         <element name="description" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
- *         <element name="filter" minOccurs="0">
- *           <complexType>
- *             <complexContent>
- *               <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *                 <sequence>
- *                   <any processContents='lax' maxOccurs="unbounded" minOccurs="0"/>
- *                 </sequence>
- *               </restriction>
- *             </complexContent>
- *           </complexType>
- *         </element>
- *       </sequence>
- *       <attribute name="oid" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="type" type="{http://www.w3.org/2001/XMLSchema}QName" />
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * + * TODO update this class by adding missing features (targetName, oid, type, relation). + * However, it's quite unclear if it's really necessary. */ @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "ObjectReferenceType", propOrder = { diff --git a/infra/prism/src/main/resources/xml/ns/public/query-3.xsd b/infra/prism/src/main/resources/xml/ns/public/query-3.xsd index 68dfe08fe2d..a22cd56f968 100644 --- a/infra/prism/src/main/resources/xml/ns/public/query-3.xsd +++ b/infra/prism/src/main/resources/xml/ns/public/query-3.xsd @@ -66,26 +66,20 @@ - + - - - + + TODO + - - - - Property which specifies matching rules. E.g. for polyString, - matching rules can be: norm, orig, strict etc. - - - + + + - - - + + @@ -165,21 +159,6 @@ - - - - - - TODO - - - - - - - - - @@ -192,38 +171,83 @@ - - - - - - - - - + + + + + + + + + + + Property which specifies matching rules. E.g. for polyString, + matching rules can be: norm, orig, strict etc. + + + + + - + - - - - XPath to the XML element for the queried property. - - - + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + An item that is to be related to the left-hand-side one. + + + @@ -252,12 +276,17 @@ - + The elements and values of queried properties. - Multi-valued properties are not allowed here. - Use "and" or "or" clauses if needed. + + + + + + + An item that is to be related to the left-hand-side one. @@ -275,7 +304,21 @@ - + + + + + + + + + + + + + @@ -296,6 +339,13 @@ + + + + If true, queries not objects with a given OID/ID, but objects that have an owner with given OID/ID. + + + @@ -310,38 +360,77 @@ - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + Object being considered can reside anywhere in the subtree rooted at base org. + + + + + + + Object being considered has to reside one level below base org. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + XPath to the XML element for the queried property. + + + + + @@ -364,15 +453,20 @@ - + - - - + + + + + + + + diff --git a/infra/prism/src/main/resources/xml/ns/public/types-3.xsd b/infra/prism/src/main/resources/xml/ns/public/types-3.xsd index 44d4c621372..c3391bf78b5 100644 --- a/infra/prism/src/main/resources/xml/ns/public/types-3.xsd +++ b/infra/prism/src/main/resources/xml/ns/public/types-3.xsd @@ -347,6 +347,18 @@ + + + +

+ The relation or a "role" of this reference. It may further specify + the meaning of the reference. E.g. it may specify whether the objects + linked by the reference are analogous, form a composition, aggregation, + are mebers of the org or managers of the org, etc. +

+
+
+
diff --git a/infra/prism/src/test/java/com/evolveum/midpoint/prism/TestDelta.java b/infra/prism/src/test/java/com/evolveum/midpoint/prism/TestDelta.java index 14dcf180a66..faec3af9b62 100644 --- a/infra/prism/src/test/java/com/evolveum/midpoint/prism/TestDelta.java +++ b/infra/prism/src/test/java/com/evolveum/midpoint/prism/TestDelta.java @@ -24,7 +24,6 @@ import java.util.Collection; import com.evolveum.midpoint.prism.delta.*; -import com.evolveum.prism.xml.ns._public.types_3.ObjectReferenceType; import org.testng.AssertJUnit; import org.testng.annotations.BeforeSuite; diff --git a/infra/schema/pom.xml b/infra/schema/pom.xml index 89ba161919e..e81b0d2efea 100644 --- a/infra/schema/pom.xml +++ b/infra/schema/pom.xml @@ -105,6 +105,21 @@ 3.4-SNAPSHOT test
+ + org.xmlunit + xmlunit-core + test + + + org.xmlunit + xmlunit-legacy + test + + + commons-io + commons-io + test + diff --git a/infra/schema/src/test/java/com/evolveum/midpoint/schema/TestQueryConvertor.java b/infra/schema/src/test/java/com/evolveum/midpoint/schema/TestQueryConvertor.java index 7286b0c702d..ff298ec0f62 100644 --- a/infra/schema/src/test/java/com/evolveum/midpoint/schema/TestQueryConvertor.java +++ b/infra/schema/src/test/java/com/evolveum/midpoint/schema/TestQueryConvertor.java @@ -16,70 +16,46 @@ package com.evolveum.midpoint.schema; -import static com.evolveum.midpoint.prism.util.PrismTestUtil.*; -import static org.testng.AssertJUnit.*; - -import java.io.File; -import java.io.IOException; -import java.util.List; - -import javax.xml.namespace.QName; - -import com.evolveum.midpoint.prism.PrismContext; -import com.evolveum.midpoint.prism.parser.DomParser; +import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.prism.parser.QueryConvertor; -import com.evolveum.midpoint.prism.query.OrgFilter; -import com.evolveum.midpoint.prism.query.builder.QueryBuilder; -import com.evolveum.midpoint.prism.util.PrismTestUtil; -import com.evolveum.midpoint.prism.util.PrismUtil; - -import com.evolveum.midpoint.prism.xnode.RootXNode; -import com.evolveum.midpoint.xml.ns._public.common.common_3.OrgType; -import org.apache.commons.lang.StringUtils; -import org.testng.annotations.BeforeSuite; -import org.testng.annotations.Test; -import org.w3c.dom.Element; -import org.xml.sax.SAXException; - -import com.evolveum.midpoint.prism.PrismConstants; -import com.evolveum.midpoint.prism.PrismObjectDefinition; -import com.evolveum.midpoint.prism.PrismPropertyDefinition; -import com.evolveum.midpoint.prism.PrismPropertyValue; -import com.evolveum.midpoint.prism.PrismReferenceValue; -import com.evolveum.midpoint.prism.PrismValue; import com.evolveum.midpoint.prism.path.ItemPath; -import com.evolveum.midpoint.prism.query.AndFilter; -import com.evolveum.midpoint.prism.query.EqualFilter; -import com.evolveum.midpoint.prism.query.LogicalFilter; -import com.evolveum.midpoint.prism.query.NaryLogicalFilter; -import com.evolveum.midpoint.prism.query.ObjectFilter; -import com.evolveum.midpoint.prism.query.ObjectPaging; -import com.evolveum.midpoint.prism.query.ObjectQuery; -import com.evolveum.midpoint.prism.query.OrFilter; -import com.evolveum.midpoint.prism.query.QueryJaxbConvertor; -import com.evolveum.midpoint.prism.query.RefFilter; -import com.evolveum.midpoint.prism.query.TypeFilter; +import com.evolveum.midpoint.prism.polystring.PolyString; +import com.evolveum.midpoint.prism.query.*; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.prism.util.PrismAsserts; +import com.evolveum.midpoint.prism.util.PrismTestUtil; import com.evolveum.midpoint.prism.xnode.ListXNode; import com.evolveum.midpoint.prism.xnode.MapXNode; import com.evolveum.midpoint.schema.constants.MidPointConstants; +import com.evolveum.midpoint.schema.constants.ObjectTypes; +import com.evolveum.midpoint.schema.util.ObjectTypeUtil; import com.evolveum.midpoint.util.DOMUtil; import com.evolveum.midpoint.util.DomAsserts; import com.evolveum.midpoint.util.PrettyPrinter; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ConnectorType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.FailedOperationTypeType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.GenericObjectType; -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.ShadowType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import com.evolveum.prism.xml.ns._public.query_3.PagingType; import com.evolveum.prism.xml.ns._public.query_3.QueryType; import com.evolveum.prism.xml.ns._public.query_3.SearchFilterType; import com.evolveum.prism.xml.ns._public.types_3.PolyStringType; +import org.apache.commons.io.FileUtils; +import org.custommonkey.xmlunit.XMLAssert; +import org.testng.annotations.BeforeSuite; +import org.testng.annotations.Test; +import org.w3c.dom.Element; +import org.xml.sax.SAXException; + +import javax.xml.namespace.QName; +import java.io.File; +import java.io.IOException; +import java.util.List; + +import static com.evolveum.midpoint.prism.PrismConstants.T_PARENT; +import static com.evolveum.midpoint.prism.util.PrismTestUtil.*; +import static com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationCampaignType.F_OWNER_REF; +import static org.testng.AssertJUnit.*; public class TestQueryConvertor { @@ -335,6 +311,14 @@ private QueryType toQueryType(ObjectQuery query) throws Exception { return QueryJaxbConvertor.createQueryType(query, getPrismContext()); } + private QueryType toQueryType(String xml) throws SchemaException { + return PrismTestUtil.parseAtomicValue(xml, QueryType.COMPLEX_TYPE); + } + + private String toXml(QueryType q1jaxb) throws SchemaException { + return getPrismContext().serializeAtomicValue(q1jaxb, SchemaConstantsGenerated.Q_QUERY, PrismContext.LANG_XML); + } + @Test public void testGenericQuery() throws Exception { displayTestTitle("testGenericQuery"); @@ -417,118 +401,279 @@ public void testConvertQueryNullFilter() throws Exception { } - @Test - public void test100OrgFilterRoot() throws Exception { - displayTestTitle("test100OrgFilterRoot"); - - ObjectQuery query = QueryBuilder.queryFor(OrgType.class, getPrismContext()).isRoot().build(); - String expected = " true "; + private void checkQuery(Class objectClass, ObjectQuery q1object, String q2xml) throws Exception { + // step 1 (serialization of Q1 + comparison) + displayText("Query 1:"); + displayQuery(q1object); + QueryType q1jaxb = toQueryType(q1object); + displayQueryType(q1jaxb); + String q1xml = toXml(q1jaxb); + displayQueryXml(q1xml); + XMLAssert.assertXMLEqual("Serialized query is not correct: Expected:\n" + q2xml + "\n\nReal:\n" + q1xml, q2xml, q1xml); + + // step 2 (parsing of Q2 + comparison) + displayText("Query 2:"); + displayQueryXml(q2xml); + QueryType q2jaxb = toQueryType(q2xml); + displayQueryType(q2jaxb); + ObjectQuery q2object = toObjectQuery(objectClass, q2jaxb); + assertEquals("Reparsed query is not as original one (via toString)", q1object.toString(), q2object.toString()); // primitive way of comparing parsed queries + assertTrue("Reparsed query is not as original one (via equivalent):\nq1="+q1object+"\nq2="+q2object, q1object.equivalent(q2object)); + } - checkQuery(query, expected); + private void checkQueryRoundtrip(Class objectClass, ObjectQuery q1object, String q2xml) throws Exception { + checkQuery(objectClass, q1object, q2xml); + String q1xml = toXml(toQueryType(q1object)); + ObjectQuery q2object = toObjectQuery(objectClass, toQueryType(q2xml)); + checkQuery(objectClass, q2object, q1xml); } - protected void checkQuery(ObjectQuery query, String expected) throws Exception { - displayQuery(query); + private void checkQueryRoundtripFile(Class objectClass, ObjectQuery query, String testName) throws Exception { + String fileName = TEST_DIR + "/" + testName + ".xml"; + checkQueryRoundtrip(objectClass, query, FileUtils.readFileToString(new File(fileName))); + } - QueryType queryType = toQueryType(query); - displayQueryType(queryType); + @Test + public void test100All() throws Exception { + final String TEST_NAME = "test100All"; + displayTestTitle(TEST_NAME); + ObjectQuery q = QueryBuilder.queryFor(UserType.class, getPrismContext()).all().build(); + checkQueryRoundtripFile(UserType.class, q, TEST_NAME); + } - assertXml(queryType, expected); + @Test + public void test110None() throws Exception { + final String TEST_NAME = "test110None"; + displayTestTitle(TEST_NAME); + ObjectQuery q = QueryBuilder.queryFor(UserType.class, getPrismContext()).none().build(); + checkQueryRoundtripFile(UserType.class, q, TEST_NAME); + } - ObjectQuery query2 = toObjectQuery(OrgType.class, queryType); - displayQuery(query2); + @Test + public void test120Undefined() throws Exception { + final String TEST_NAME = "test120Undefined"; + displayTestTitle(TEST_NAME); + ObjectQuery q = QueryBuilder.queryFor(UserType.class, getPrismContext()).undefined().build(); + checkQueryRoundtripFile(UserType.class, q, TEST_NAME); + } - // primitive way of comparing queries - assertEquals("Reparsed query is not as original one", query.toString(), query2.toString()); + @Test + public void test200Equal() throws Exception { + final String TEST_NAME = "test200Equal"; + displayTestTitle(TEST_NAME); + ObjectQuery q = QueryBuilder.queryFor(UserType.class, getPrismContext()) + .item(UserType.F_NAME).eqPoly("some-name", "somename").matchingOrig() + .build(); + checkQueryRoundtripFile(UserType.class, q, TEST_NAME); + } - QueryType queryType2 = toQueryType(query2); - displayQueryType(queryType2); + @Test + public void test210EqualMultiple() throws Exception { + final String TEST_NAME = "test210EqualMultiple"; + displayTestTitle(TEST_NAME); + ObjectQuery q = QueryBuilder.queryFor(UserType.class, getPrismContext()) + .item(UserType.F_EMPLOYEE_TYPE).eq("STD", "TEMP") + .build(); + checkQueryRoundtripFile(UserType.class, q, TEST_NAME); + } - assertEquals("Reserialized query type is not as original one", queryType, queryType2); + @Test + public void test220EqualRightHandItem() throws Exception { + final String TEST_NAME = "test220EqualRightHandItem"; + displayTestTitle(TEST_NAME); + PrismObjectDefinition userDef = getPrismContext().getSchemaRegistry().findObjectDefinitionByCompileTimeClass(UserType.class); + ObjectQuery q = QueryBuilder.queryFor(UserType.class, getPrismContext()) + .item(UserType.F_EMPLOYEE_NUMBER).eq().item(new ItemPath(UserType.F_COST_CENTER), userDef.findItemDefinition(UserType.F_COST_CENTER)) + .build(); + checkQueryRoundtripFile(UserType.class, q, TEST_NAME); } @Test - public void test110OrgFilterSubtree() throws Exception { - displayTestTitle("test110OrgFilterSubtree"); + public void test300Greater() throws Exception { + final String TEST_NAME = "test300Greater"; + displayTestTitle(TEST_NAME); + ObjectQuery q = QueryBuilder.queryFor(UserType.class, getPrismContext()) + .item(UserType.F_COST_CENTER).gt("100000") + .build(); + checkQueryRoundtripFile(UserType.class, q, TEST_NAME); + } - ObjectQuery query = QueryBuilder.queryFor(OrgType.class, getPrismContext()).isChildOf("111").build(); - displayQuery(query); + @Test + public void test310AllComparisons() throws Exception { + final String TEST_NAME = "test310AllComparisons"; + displayTestTitle(TEST_NAME); + ObjectQuery q = QueryBuilder.queryFor(UserType.class, getPrismContext()) + .item(UserType.F_COST_CENTER).gt("100000") + .and().item(UserType.F_COST_CENTER).lt("999999") + .or() + .item(UserType.F_COST_CENTER).ge("X100") + .and().item(UserType.F_COST_CENTER).le("X999") + .build(); + checkQueryRoundtripFile(UserType.class, q, TEST_NAME); + } - String expected = "\n" + - " \n" + - " 111\n" + - " \n" + - " SUBTREE\n" + - " "; + @Test + public void test350Substring() throws Exception { + final String TEST_NAME = "test350Substring"; + displayTestTitle(TEST_NAME); + ObjectQuery q = QueryBuilder.queryFor(UserType.class, getPrismContext()) + .item(UserType.F_EMPLOYEE_TYPE).contains("A") + .or().item(UserType.F_EMPLOYEE_TYPE).startsWith("B") + .or().item(UserType.F_EMPLOYEE_TYPE).endsWith("C") + .or().item(UserType.F_NAME).startsWithPoly("john", "john").matchingOrig() + .build(); + checkQueryRoundtripFile(UserType.class, q, TEST_NAME); + } - checkQuery(query, expected); + @Test + public void test360Ref() throws Exception { + final String TEST_NAME = "test360Ref"; + displayTestTitle(TEST_NAME); + + // we test only parsing here, as there are more serialized forms used here + ObjectQuery q1object = QueryBuilder.queryFor(ShadowType.class, getPrismContext()) + .item(ShadowType.F_RESOURCE_REF).ref("oid1") + .or().item(ShadowType.F_RESOURCE_REF).ref("oid2", ResourceType.COMPLEX_TYPE) + .or().item(ShadowType.F_RESOURCE_REF).ref("oid3") + .or().item(ShadowType.F_RESOURCE_REF).ref("oid4", ResourceType.COMPLEX_TYPE) + .build(); + String q2xml = FileUtils.readFileToString(new File(TEST_DIR + "/" + TEST_NAME + ".xml")); + displayQueryXml(q2xml); + QueryType q2jaxb = toQueryType(q2xml); + displayQueryType(q2jaxb); + ObjectQuery q2object = toObjectQuery(ShadowType.class, q2jaxb); + assertEquals("Reparsed query is not as original one (via toString)", q1object.toString(), q2object.toString()); // primitive way of comparing parsed queries + assertTrue("Reparsed query is not as original one (via equivalent):\nq1="+q1object+"\nq2="+q2object, q1object.equivalent(q2object)); } @Test - public void test120OrgFilterDirect() throws Exception { - displayTestTitle("test120OrgFilterDirect"); + public void test365RefTwoWay() throws Exception { + final String TEST_NAME = "test365RefTwoWay"; + displayTestTitle(TEST_NAME); + PrismReferenceValue reference3 = new PrismReferenceValue("oid3", ResourceType.COMPLEX_TYPE); + reference3.setRelation(new QName("test")); + ObjectQuery q = QueryBuilder.queryFor(ShadowType.class, getPrismContext()) + .item(ShadowType.F_RESOURCE_REF).ref("oid1") + .or().item(ShadowType.F_RESOURCE_REF).ref("oid2", ResourceType.COMPLEX_TYPE) + .or().item(ShadowType.F_RESOURCE_REF).ref(reference3) + .build(); + checkQueryRoundtripFile(ShadowType.class, q, TEST_NAME); + } - ObjectQuery query = QueryBuilder.queryFor(OrgType.class, getPrismContext()).isDirectChildOf("222").build(); - displayQuery(query); + @Test + public void test400OrgFilterRoot() throws Exception { + final String TEST_NAME = "test400OrgFilterRoot"; + displayTestTitle(TEST_NAME); + ObjectQuery q = QueryBuilder.queryFor(OrgType.class, getPrismContext()).isRoot().build(); + checkQueryRoundtripFile(OrgType.class, q, TEST_NAME); + } - String expected = "\n" + - " \n" + - " 222\n" + - " \n" + - " ONE_LEVEL\n" + - " "; + @Test + public void test410OrgFilterSubtree() throws Exception { + final String TEST_NAME = "test410OrgFilterSubtree"; + displayTestTitle(TEST_NAME); + ObjectQuery q = QueryBuilder.queryFor(OrgType.class, getPrismContext()).isChildOf("111").build(); + checkQueryRoundtripFile(OrgType.class, q, TEST_NAME); + } - checkQuery(query, expected); + @Test + public void test420OrgFilterDirect() throws Exception { + final String TEST_NAME = "test420OrgFilterDirect"; + displayTestTitle(TEST_NAME); + ObjectQuery q = QueryBuilder.queryFor(OrgType.class, getPrismContext()).isDirectChildOf("222").build(); + checkQueryRoundtripFile(OrgType.class, q, TEST_NAME); } @Test - public void test130OrgFilterDefaultScope() throws Exception { - displayTestTitle("test130OrgFilterDefaultScope"); + public void test430OrgFilterDefaultScope() throws Exception { + final String TEST_NAME = "test430OrgFilterDefaultScope"; + displayTestTitle(TEST_NAME); - String filterText = "\n" + + // default scope is SUBTREE + String queryXml = "\n" + " \n" + " 333\n" + " \n" + - " "; - - SearchFilterType filterType = getPrismContext().parseAtomicValue(filterText, SearchFilterType.COMPLEX_TYPE, PrismContext.LANG_XML); - displaySearchFilterType(filterType); - - ObjectFilter filter = QueryConvertor.parseFilter(filterType, OrgType.class, getPrismContext()); - ObjectQuery query = ObjectQuery.createObjectQuery(filter); + " "; + QueryType queryJaxb = toQueryType(queryXml); + displayQueryType(queryJaxb); + ObjectQuery query = toObjectQuery(OrgType.class, queryJaxb); + displayQuery(query); ObjectQuery expectedQuery = QueryBuilder.queryFor(OrgType.class, getPrismContext()).isChildOf("333").build(); - // primitive way of comparing queries - assertEquals("Parsed query is wrong", expectedQuery.toString(), query.toString()); + assertEquals("Parsed query is wrong", expectedQuery.toString(), query.toString()); // primitive way of comparing queries - // now reserialize the parsed query and compare with XML - String expected = "\n" + - " \n" + - " 333\n" + - " \n" + - " SUBTREE\n" + - " "; + // now reserialize the parsed query and compare with XML - the XML contains explicit scope=SUBTREE (as this is set when parsing original queryXml) + checkQueryRoundtripFile(OrgType.class, query, TEST_NAME); + } - checkQuery(query, expected); + @Test + public void test500InOid() throws Exception { + final String TEST_NAME = "test500InOid"; + displayTestTitle(TEST_NAME); + ObjectQuery q = QueryBuilder.queryFor(UserType.class, getPrismContext()) + .id("oid1", "oid2", "oid3") + .build(); + checkQueryRoundtripFile(UserType.class, q, TEST_NAME); } + @Test + public void test510InOidContainer() throws Exception { + final String TEST_NAME = "test510InOidContainer"; + displayTestTitle(TEST_NAME); + ObjectQuery q = QueryBuilder.queryFor(UserType.class, getPrismContext()) + .id(1, 2, 3) + .and().ownerId("oid4") + .build(); + checkQueryRoundtripFile(UserType.class, q, TEST_NAME); + } - private void assertXml(QueryType queryType, String expected) throws SchemaException { - MapXNode mapXNode = queryType.getFilter().getFilterClauseXNode(); - String realWrapped = getPrismContext().serializeXNodeToString(new RootXNode(new QName("query"), mapXNode), PrismContext.LANG_XML); + @Test + public void test590Logicals() throws Exception { + final String TEST_NAME = "test590Logicals"; + displayTestTitle(TEST_NAME); + ObjectQuery q = QueryBuilder.queryFor(UserType.class, getPrismContext()) + .block() + .all() + .or().none() + .or().undefined() + .endBlock() + .and().none() + .and() + .not() + .block() + .all() + .and().undefined() + .endBlock() + .build(); + checkQueryRoundtripFile(UserType.class, q, TEST_NAME); + } - // primitive but effective method - int start = realWrapped.indexOf('>')+1; - int end = realWrapped.lastIndexOf('<'); - String real = realWrapped.substring(start, end); + @Test + public void test600Type() throws Exception { + final String TEST_NAME = "test600Type"; + displayTestTitle(TEST_NAME); + ObjectQuery q = QueryBuilder.queryFor(ObjectType.class, getPrismContext()) + .type(UserType.class) + .item(UserType.F_NAME).eqPoly("somename", "somename") + .build(); + checkQueryRoundtripFile(ObjectType.class, q, TEST_NAME); + } - String expNorm = StringUtils.normalizeSpace(expected); - String realNorm = StringUtils.normalizeSpace(real); - if (!expNorm.equals(realNorm)) { - String m = "Serialized query is not correct. Expected:\n" + expected + "\nActual:\n" + real + "\n\nNormalized versions:\n\n" + - "Expected: " + expNorm + "\nActual: " + realNorm + "\n"; - LOGGER.error("{}", m); - throw new AssertionError(m); - } + @Test + public void test700Exists() throws Exception { + final String TEST_NAME = "test700Exists"; + displayTestTitle(TEST_NAME); + PrismReferenceValue ownerRef = ObjectTypeUtil.createObjectRef("1234567890", ObjectTypes.USER).asReferenceValue(); + ObjectQuery q = QueryBuilder.queryFor(AccessCertificationCaseType.class, getPrismContext()) + .exists(T_PARENT) + .block() + .id(123456L) + .or().item(F_OWNER_REF).ref(ownerRef) + .endBlock() + .and().item(AccessCertificationCaseType.F_DECISION, AccessCertificationDecisionType.F_STAGE_NUMBER).eq(3) + .build(); + checkQueryRoundtripFile(AccessCertificationCaseType.class, q, TEST_NAME); } + } diff --git a/infra/schema/src/test/java/com/evolveum/midpoint/schema/test/XPathTest.java b/infra/schema/src/test/java/com/evolveum/midpoint/schema/test/XPathTest.java index 2504001c6d4..f25726d16da 100644 --- a/infra/schema/src/test/java/com/evolveum/midpoint/schema/test/XPathTest.java +++ b/infra/schema/src/test/java/com/evolveum/midpoint/schema/test/XPathTest.java @@ -390,6 +390,23 @@ public void testXPathSerializationToDom() { assertTrue("Paths are not equivalent", xpath1.equivalent(xpath2)); } + @Test + public void parseSpecial() { + final String D = "declare namespace x='http://xyz.com/'; "; + AssertJUnit.assertEquals("..", TrivialXPathParser.parse("..").getPureXPathString()); + AssertJUnit.assertEquals("..", TrivialXPathParser.parse(D+"..").getPureXPathString()); + AssertJUnit.assertEquals("a/../b", TrivialXPathParser.parse("a/../b").getPureXPathString()); + AssertJUnit.assertEquals("a/../b", TrivialXPathParser.parse(D+"a/../b").getPureXPathString()); + AssertJUnit.assertEquals("@", TrivialXPathParser.parse("@").getPureXPathString()); + AssertJUnit.assertEquals("@", TrivialXPathParser.parse(D+"@").getPureXPathString()); + AssertJUnit.assertEquals("a/@/b", TrivialXPathParser.parse("a/@/b").getPureXPathString()); + AssertJUnit.assertEquals("a/@/b", TrivialXPathParser.parse(D+"a/@/b").getPureXPathString()); + AssertJUnit.assertEquals("#", TrivialXPathParser.parse("#").getPureXPathString()); + AssertJUnit.assertEquals("#", TrivialXPathParser.parse(D+"#").getPureXPathString()); + AssertJUnit.assertEquals("a/#/b", TrivialXPathParser.parse("a/#/b").getPureXPathString()); + AssertJUnit.assertEquals("a/#/b", TrivialXPathParser.parse(D+"a/#/b").getPureXPathString()); + } + //not actual anymore..we have something like "wildcard" in xpath..there don't need to be prefix specified.we will try to match the local names @Test(enabled=false) public void testUndefinedPrefix() throws ParserConfigurationException, SAXException, IOException { diff --git a/infra/schema/src/test/resources/queryconvertor/filter-account.xml b/infra/schema/src/test/resources/queryconvertor/filter-account.xml index 7683fcd99e3..27769b9f175 100644 --- a/infra/schema/src/test/resources/queryconvertor/filter-account.xml +++ b/infra/schema/src/test/resources/queryconvertor/filter-account.xml @@ -23,14 +23,14 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + insensitive c:failedOperationType add - insensitive + norm c:name someName - norm diff --git a/infra/schema/src/test/resources/queryconvertor/test100All.xml b/infra/schema/src/test/resources/queryconvertor/test100All.xml new file mode 100644 index 00000000000..9afe2237d9a --- /dev/null +++ b/infra/schema/src/test/resources/queryconvertor/test100All.xml @@ -0,0 +1,22 @@ + + + + + + + + \ No newline at end of file diff --git a/infra/schema/src/test/resources/queryconvertor/test110None.xml b/infra/schema/src/test/resources/queryconvertor/test110None.xml new file mode 100644 index 00000000000..3d517890aa6 --- /dev/null +++ b/infra/schema/src/test/resources/queryconvertor/test110None.xml @@ -0,0 +1,22 @@ + + + + + + + + \ No newline at end of file diff --git a/infra/schema/src/test/resources/queryconvertor/test120Undefined.xml b/infra/schema/src/test/resources/queryconvertor/test120Undefined.xml new file mode 100644 index 00000000000..8aa2d35922e --- /dev/null +++ b/infra/schema/src/test/resources/queryconvertor/test120Undefined.xml @@ -0,0 +1,22 @@ + + + + + + + + \ No newline at end of file diff --git a/infra/schema/src/test/resources/queryconvertor/test200Equal.xml b/infra/schema/src/test/resources/queryconvertor/test200Equal.xml new file mode 100644 index 00000000000..af154eaa559 --- /dev/null +++ b/infra/schema/src/test/resources/queryconvertor/test200Equal.xml @@ -0,0 +1,26 @@ + + + + + + + polyStringOrig + c:name + some-name + + + \ No newline at end of file diff --git a/infra/schema/src/test/resources/queryconvertor/test210EqualMultiple.xml b/infra/schema/src/test/resources/queryconvertor/test210EqualMultiple.xml new file mode 100644 index 00000000000..640931bc0e2 --- /dev/null +++ b/infra/schema/src/test/resources/queryconvertor/test210EqualMultiple.xml @@ -0,0 +1,26 @@ + + + + + + + c:employeeType + STD + TEMP + + + \ No newline at end of file diff --git a/infra/schema/src/test/resources/queryconvertor/test220EqualRightHandItem.xml b/infra/schema/src/test/resources/queryconvertor/test220EqualRightHandItem.xml new file mode 100644 index 00000000000..75c224da2cc --- /dev/null +++ b/infra/schema/src/test/resources/queryconvertor/test220EqualRightHandItem.xml @@ -0,0 +1,25 @@ + + + + + + + c:employeeNumber + c:costCenter + + + \ No newline at end of file diff --git a/infra/schema/src/test/resources/queryconvertor/test300Greater.xml b/infra/schema/src/test/resources/queryconvertor/test300Greater.xml new file mode 100644 index 00000000000..55866880985 --- /dev/null +++ b/infra/schema/src/test/resources/queryconvertor/test300Greater.xml @@ -0,0 +1,25 @@ + + + + + + + c:costCenter + 100000 + + + \ No newline at end of file diff --git a/infra/schema/src/test/resources/queryconvertor/test310AllComparisons.xml b/infra/schema/src/test/resources/queryconvertor/test310AllComparisons.xml new file mode 100644 index 00000000000..6f5c071d606 --- /dev/null +++ b/infra/schema/src/test/resources/queryconvertor/test310AllComparisons.xml @@ -0,0 +1,43 @@ + + + + + + + + + c:costCenter + 100000 + + + c:costCenter + 999999 + + + + + c:costCenter + X100 + + + c:costCenter + X999 + + + + + \ No newline at end of file diff --git a/infra/schema/src/test/resources/queryconvertor/test350Substring.xml b/infra/schema/src/test/resources/queryconvertor/test350Substring.xml new file mode 100644 index 00000000000..01222881c54 --- /dev/null +++ b/infra/schema/src/test/resources/queryconvertor/test350Substring.xml @@ -0,0 +1,43 @@ + + + + + + + + c:employeeType + A + + + c:employeeType + B + true + + + c:employeeType + C + true + + + polyStringOrig + c:name + john + true + + + + \ No newline at end of file diff --git a/infra/schema/src/test/resources/queryconvertor/test360Ref.xml b/infra/schema/src/test/resources/queryconvertor/test360Ref.xml new file mode 100644 index 00000000000..47c29112441 --- /dev/null +++ b/infra/schema/src/test/resources/queryconvertor/test360Ref.xml @@ -0,0 +1,44 @@ + + + + + + + c:resourceRef + + + + c:resourceRef + + + + c:resourceRef + + oid3 + + + + c:resourceRef + + oid4 + c:ResourceType + + + + + diff --git a/infra/schema/src/test/resources/queryconvertor/test365RefTwoWay.xml b/infra/schema/src/test/resources/queryconvertor/test365RefTwoWay.xml new file mode 100644 index 00000000000..6947676fc07 --- /dev/null +++ b/infra/schema/src/test/resources/queryconvertor/test365RefTwoWay.xml @@ -0,0 +1,38 @@ + + + + + + + + c:resourceRef + + + + c:resourceRef + + + + c:resourceRef + + + + + diff --git a/infra/schema/src/test/resources/queryconvertor/test400OrgFilterRoot.xml b/infra/schema/src/test/resources/queryconvertor/test400OrgFilterRoot.xml new file mode 100644 index 00000000000..edb54e11978 --- /dev/null +++ b/infra/schema/src/test/resources/queryconvertor/test400OrgFilterRoot.xml @@ -0,0 +1,24 @@ + + + + + + + true + + + diff --git a/infra/schema/src/test/resources/queryconvertor/test410OrgFilterSubtree.xml b/infra/schema/src/test/resources/queryconvertor/test410OrgFilterSubtree.xml new file mode 100644 index 00000000000..8e9dfe13d28 --- /dev/null +++ b/infra/schema/src/test/resources/queryconvertor/test410OrgFilterSubtree.xml @@ -0,0 +1,11 @@ + + + + + + 111 + + SUBTREE + + + diff --git a/infra/schema/src/test/resources/queryconvertor/test420OrgFilterDirect.xml b/infra/schema/src/test/resources/queryconvertor/test420OrgFilterDirect.xml new file mode 100644 index 00000000000..9b70a5b7de5 --- /dev/null +++ b/infra/schema/src/test/resources/queryconvertor/test420OrgFilterDirect.xml @@ -0,0 +1,27 @@ + + + + + + + + 222 + + ONE_LEVEL + + + diff --git a/infra/schema/src/test/resources/queryconvertor/test430OrgFilterDefaultScope.xml b/infra/schema/src/test/resources/queryconvertor/test430OrgFilterDefaultScope.xml new file mode 100644 index 00000000000..fd6d012bb8a --- /dev/null +++ b/infra/schema/src/test/resources/queryconvertor/test430OrgFilterDefaultScope.xml @@ -0,0 +1,27 @@ + + + + + + + + 333 + + SUBTREE + + + diff --git a/infra/schema/src/test/resources/queryconvertor/test500InOid.xml b/infra/schema/src/test/resources/queryconvertor/test500InOid.xml new file mode 100644 index 00000000000..1fb18e3077d --- /dev/null +++ b/infra/schema/src/test/resources/queryconvertor/test500InOid.xml @@ -0,0 +1,26 @@ + + + + + + + oid1 + oid2 + oid3 + + + diff --git a/infra/schema/src/test/resources/queryconvertor/test510InOidContainer.xml b/infra/schema/src/test/resources/queryconvertor/test510InOidContainer.xml new file mode 100644 index 00000000000..80396209e0f --- /dev/null +++ b/infra/schema/src/test/resources/queryconvertor/test510InOidContainer.xml @@ -0,0 +1,32 @@ + + + + + + + + 1 + 2 + 3 + + + oid4 + true + + + + diff --git a/infra/schema/src/test/resources/queryconvertor/test590Logicals.xml b/infra/schema/src/test/resources/queryconvertor/test590Logicals.xml new file mode 100644 index 00000000000..7b121ef1be2 --- /dev/null +++ b/infra/schema/src/test/resources/queryconvertor/test590Logicals.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/infra/schema/src/test/resources/queryconvertor/test600Type.xml b/infra/schema/src/test/resources/queryconvertor/test600Type.xml new file mode 100644 index 00000000000..cd98eda2518 --- /dev/null +++ b/infra/schema/src/test/resources/queryconvertor/test600Type.xml @@ -0,0 +1,30 @@ + + + + + + + c:UserType + + + c:name + somename + + + + + diff --git a/infra/schema/src/test/resources/queryconvertor/test700Exists.xml b/infra/schema/src/test/resources/queryconvertor/test700Exists.xml new file mode 100644 index 00000000000..1714108be92 --- /dev/null +++ b/infra/schema/src/test/resources/queryconvertor/test700Exists.xml @@ -0,0 +1,44 @@ + + + + + + + + .. + + + + 123456 + + + c:ownerRef + + + + + + + c:decision/c:stageNumber + 3 + + + + diff --git a/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/AccCertQueryHelper.java b/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/AccCertQueryHelper.java index c85149d7899..9f7ba7be4ee 100644 --- a/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/AccCertQueryHelper.java +++ b/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/AccCertQueryHelper.java @@ -178,15 +178,10 @@ public List searchDecisions(ObjectQuery query, Stri private ObjectFilter getReviewerAndEnabledFilter(String reviewerOid) throws SchemaException { // we have to find definition ourselves, as ../state cannot be currently resolved by query builder - ItemPath statePath = new ItemPath(T_PARENT, F_STATE); - PrismPropertyDefinition stateDef = - prismContext.getSchemaRegistry() - .findComplexTypeDefinitionByCompileTimeClass(AccessCertificationCampaignType.class) - .findPropertyDefinition(F_STATE); return QueryBuilder.queryFor(AccessCertificationCaseType.class, prismContext) .item(F_CURRENT_REVIEWER_REF).ref(reviewerOid, UserType.COMPLEX_TYPE) .and().item(F_CURRENT_STAGE_NUMBER).eq().item(T_PARENT, AccessCertificationCampaignType.F_STAGE_NUMBER) - .and().item(statePath, stateDef).eq(IN_REVIEW_STAGE) + .and().item(T_PARENT, F_STATE).eq(IN_REVIEW_STAGE) .buildFilter(); } diff --git a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/CertificationTest.java b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/CertificationTest.java index 648abfde642..8c969f10f5b 100644 --- a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/CertificationTest.java +++ b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/CertificationTest.java @@ -408,14 +408,9 @@ public void test330CurrentUnansweredCases() throws Exception { OperationResult result = new OperationResult("test330CurrentUnansweredCases"); // we have to find definition ourselves, as ../state cannot be currently resolved by query builder - ItemPath statePath = new ItemPath(T_PARENT, F_STATE); - PrismPropertyDefinition stateDef = - prismContext.getSchemaRegistry() - .findComplexTypeDefinitionByCompileTimeClass(AccessCertificationCampaignType.class) - .findPropertyDefinition(F_STATE); ObjectQuery query = QueryBuilder.queryFor(AccessCertificationCaseType.class, prismContext) .item(F_CURRENT_STAGE_NUMBER).eq().item(T_PARENT, AccessCertificationCampaignType.F_STAGE_NUMBER) - .and().item(statePath, stateDef).eq(IN_REVIEW_STAGE) + .and().item(T_PARENT, F_STATE).eq(IN_REVIEW_STAGE) .and().exists(F_DECISION).block() .item(F_STAGE_NUMBER).eq().item(T_PARENT, F_CURRENT_STAGE_NUMBER) .and().block() diff --git a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/QueryInterpreter2Test.java b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/QueryInterpreter2Test.java index 1a764e817fb..1225d61f581 100644 --- a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/QueryInterpreter2Test.java +++ b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/QueryInterpreter2Test.java @@ -2814,13 +2814,11 @@ public void test740QueryCertCasesByCampaignOwner() throws Exception { Session session = open(); try { PrismReferenceValue ownerRef = ObjectTypeUtil.createObjectRef("1234567890", ObjectTypes.USER).asReferenceValue(); - PrismObjectDefinition campaignDef = - prismContext.getSchemaRegistry().findObjectDefinitionByCompileTimeClass(AccessCertificationCampaignType.class); ObjectQuery query = QueryBuilder.queryFor(AccessCertificationCaseType.class, prismContext) .exists(T_PARENT) .block() .id(123456L) - .or().item(campaignDef, F_OWNER_REF).ref(ownerRef) + .or().item(F_OWNER_REF).ref(ownerRef) .endBlock() .build(); @@ -2932,15 +2930,10 @@ public void test747QueryCertCaseReviewerAndEnabledByRequestedDesc() throws Excep Session session = open(); try { PrismReferenceValue reviewerRef = ObjectTypeUtil.createObjectRef("1234567890", ObjectTypes.USER).asReferenceValue(); - ItemPath statePath = new ItemPath(T_PARENT, F_STATE); - PrismPropertyDefinition stateDef = - prismContext.getSchemaRegistry() - .findComplexTypeDefinitionByCompileTimeClass(AccessCertificationCampaignType.class) - .findPropertyDefinition(F_STATE); ObjectQuery query = QueryBuilder.queryFor(AccessCertificationCaseType.class, prismContext) .item(F_CURRENT_REVIEWER_REF).ref(reviewerRef) .and().item(F_CURRENT_STAGE_NUMBER).eq().item(T_PARENT, AccessCertificationCampaignType.F_STAGE_NUMBER) - .and().item(statePath, stateDef).eq(IN_REVIEW_STAGE) + .and().item(T_PARENT, F_STATE).eq(IN_REVIEW_STAGE) .desc(F_CURRENT_REVIEW_REQUESTED_TIMESTAMP) .build(); String real = getInterpretedQuery2(session, AccessCertificationCaseType.class, query, false); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/ObjectPagingAfterOid.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/ObjectPagingAfterOid.java index 5fab50e5165..8e9f3c79521 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/ObjectPagingAfterOid.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/ObjectPagingAfterOid.java @@ -52,4 +52,25 @@ protected void copyTo(ObjectPagingAfterOid clone) { super.copyTo(clone); clone.oidGreaterThan = this.oidGreaterThan; } + + public boolean equals(Object o, boolean exact) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + if (!super.equals(o, exact)) + return false; + + ObjectPagingAfterOid that = (ObjectPagingAfterOid) o; + + return oidGreaterThan != null ? oidGreaterThan.equals(that.oidGreaterThan) : that.oidGreaterThan == null; + + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + (oidGreaterThan != null ? oidGreaterThan.hashCode() : 0); + return result; + } } diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/restriction/AnyPropertyRestriction.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/restriction/AnyPropertyRestriction.java index 2ee593c12fb..117e22311ee 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/restriction/AnyPropertyRestriction.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/restriction/AnyPropertyRestriction.java @@ -44,7 +44,7 @@ public Condition interpretInternal() throws QueryException { String propertyValuePath = getHqlDataInstance().getHqlPath(); - if (filter.getRightSidePath() != null) { + if (filter.getRightHandSidePath() != null) { return createPropertyVsPropertyCondition(propertyValuePath); } else { Object value = RAnyConverter.getAggregatedRepoObject(getValue(filter)); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/restriction/PropertyRestriction.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/restriction/PropertyRestriction.java index fbf7fc5baac..35d9cf7ce18 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/restriction/PropertyRestriction.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/restriction/PropertyRestriction.java @@ -65,7 +65,7 @@ public Condition interpretInternal() throws QueryException { } String propertyValuePath = getHqlDataInstance().getHqlPath(); - if (filter.getRightSidePath() != null) { + if (filter.getRightHandSidePath() != null) { return createPropertyVsPropertyCondition(propertyValuePath); } else { Object value = getValueFromFilter(filter); @@ -75,8 +75,8 @@ public Condition interpretInternal() throws QueryException { } protected Condition createPropertyVsPropertyCondition(String leftPropertyValuePath) throws QueryException { - HqlDataInstance rightItem = getItemPathResolver().resolveItemPath(filter.getRightSidePath(), - filter.getRightSideDefinition(), getBaseHqlEntityForChildren(), true); + HqlDataInstance rightItem = getItemPathResolver().resolveItemPath(filter.getRightHandSidePath(), + filter.getRightHandSideDefinition(), getBaseHqlEntityForChildren(), true); String rightHqlPath = rightItem.getHqlPath(); RootHibernateQuery hibernateQuery = context.getHibernateQuery(); diff --git a/samples/model-client-sample/src/main/java/com/evolveum/midpoint/testing/model/client/sample/Main.java b/samples/model-client-sample/src/main/java/com/evolveum/midpoint/testing/model/client/sample/Main.java index 6b6cab195bd..9ee673fe979 100644 --- a/samples/model-client-sample/src/main/java/com/evolveum/midpoint/testing/model/client/sample/Main.java +++ b/samples/model-client-sample/src/main/java/com/evolveum/midpoint/testing/model/client/sample/Main.java @@ -511,7 +511,7 @@ private static QueryType createUserQuery2(String username) throws JAXBException ItemPathType path = new ItemPathType(); path.setValue("declare namespace c=\"http://midpoint.evolveum.com/xml/ns/public/common/common-3\"; c:name"); fc.setPath(path); - fc.setValue(username); + fc.getValue().add(username); ObjectFactory factory = new ObjectFactory(); JAXBElement equal = factory.createEqual(fc);