/* * Copyright (c) 2010-2015 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.evolveum.midpoint.prism.query; import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.prism.foo.AssignmentType; import com.evolveum.midpoint.prism.foo.UserType; import com.evolveum.midpoint.prism.match.MatchingRuleRegistry; import com.evolveum.midpoint.prism.match.MatchingRuleRegistryFactory; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.prism.util.PrismTestUtil; import com.evolveum.midpoint.util.PrettyPrinter; import com.evolveum.midpoint.util.exception.SchemaException; import com.sun.tools.xjc.reader.xmlschema.bindinfo.BIConversion; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.testng.AssertJUnit; import org.testng.annotations.BeforeMethod; import org.testng.annotations.BeforeSuite; import org.testng.annotations.Test; import org.xml.sax.SAXException; import javax.xml.namespace.QName; import java.io.IOException; import java.lang.reflect.Method; import static com.evolveum.midpoint.prism.PrismInternalTestUtil.DEFAULT_NAMESPACE_PREFIX; import static com.evolveum.midpoint.prism.PrismInternalTestUtil.NS_FOO; import static com.evolveum.midpoint.prism.util.PrismTestUtil.getPrismContext; import static com.evolveum.midpoint.prism.util.PrismTestUtil.getSchemaRegistry; /** * Here are the most simple tests for Query Builder. * More advanced tests are part of QueryInterpreterTest in repo-sql-impl-test. * * These tests are strict in the sense they check the exact structure of created queries. * Repo tests check just the HQL outcome. */ public class TestQueryBuilder { public static final QName USER_TYPE_QNAME = new QName(NS_FOO, "UserType"); public static final QName ASSIGNMENT_TYPE_QNAME = new QName(NS_FOO, "AssignmentType"); private static MatchingRuleRegistry matchingRuleRegistry; @BeforeSuite public void setupDebug() throws SchemaException, SAXException, IOException { PrettyPrinter.setDefaultNamespacePrefix(DEFAULT_NAMESPACE_PREFIX); PrismTestUtil.resetPrismContext(new PrismInternalTestUtil()); matchingRuleRegistry = MatchingRuleRegistryFactory.createRegistry(); } @BeforeMethod public void beforeMethod(Method method) throws Exception { System.out.println(">>>>>>>>>>>>>>>>>>>>>>>> START TEST" + getClass().getName() + "." + method.getName() + "<<<<<<<<<<<<<<<<<<<<<<<<"); } @Test public void test100EmptyFilter() throws Exception{ ObjectQuery actual = QueryBuilder.queryFor(UserType.class, getPrismContext()).build(); ObjectQuery expected = ObjectQuery.createObjectQuery((ObjectFilter) null); compare(actual, expected); } @Test public void test110EmptyBlock() throws Exception{ ObjectQuery actual = QueryBuilder.queryFor(UserType.class, getPrismContext()).block().endBlock().build(); ObjectQuery expected = ObjectQuery.createObjectQuery((ObjectFilter) null); compare(actual, expected); } @Test public void test112EmptyBlocks() throws Exception{ ObjectQuery actual = QueryBuilder.queryFor(UserType.class, getPrismContext()) .block() .block() .block() .endBlock() .endBlock() .endBlock() .build(); ObjectQuery expected = ObjectQuery.createObjectQuery((ObjectFilter) null); compare(actual, expected); } @Test(expectedExceptions = IllegalStateException.class) public void test113BlocksLeftOpen() throws Exception{ QueryBuilder.queryFor(UserType.class, getPrismContext()) .block() .block() .block() .endBlock() .endBlock() .build(); } @Test(expectedExceptions = IllegalStateException.class) public void test114NoOpenBlocks() throws Exception{ QueryBuilder.queryFor(UserType.class, getPrismContext()) .block() .block() .endBlock() .endBlock() .endBlock() .build(); } @Test public void test120All() throws Exception{ ObjectQuery actual = QueryBuilder.queryFor(UserType.class, getPrismContext()).all().build(); ObjectQuery expected = ObjectQuery.createObjectQuery(AllFilter.createAll()); compare(actual, expected); } @Test public void test122AllInBlock() throws Exception{ ObjectQuery actual = QueryBuilder.queryFor(UserType.class, getPrismContext()).block().all().endBlock().build(); ObjectQuery expected = ObjectQuery.createObjectQuery(AllFilter.createAll()); compare(actual, expected); } @Test public void test130SingleEquals() throws Exception{ ObjectQuery actual = QueryBuilder.queryFor(UserType.class, getPrismContext()).item(UserType.F_LOCALITY).eq("Caribbean").build(); ObjectQuery expected = ObjectQuery.createObjectQuery(createEqual(UserType.F_LOCALITY, UserType.class, null, "Caribbean")); compare(actual, expected); } @Test public void test132SingleAnd() throws Exception{ ObjectQuery actual = QueryBuilder.queryFor(UserType.class, getPrismContext()) .item(UserType.F_LOCALITY).eq("Caribbean") .and().item(UserType.F_DESCRIPTION).eq("desc") .build(); ObjectQuery expected = ObjectQuery.createObjectQuery( AndFilter.createAnd( createEqual(UserType.F_LOCALITY, UserType.class, null, "Caribbean"), createEqual(UserType.F_DESCRIPTION, UserType.class, null, "desc") ) ); compare(actual, expected); } @Test public void test134SingleOrWithNot() throws Exception{ ObjectQuery actual = QueryBuilder.queryFor(UserType.class, getPrismContext()) .item(UserType.F_LOCALITY).eq("Caribbean") .or().not().item(UserType.F_DESCRIPTION).eq("desc") .build(); ObjectQuery expected = ObjectQuery.createObjectQuery( OrFilter.createOr( createEqual(UserType.F_LOCALITY, UserType.class, null, "Caribbean"), NotFilter.createNot( createEqual(UserType.F_DESCRIPTION, UserType.class, null, "desc") ) ) ); compare(actual, expected); } @Test public void test136AndOrNotSequence() throws Exception{ ObjectQuery actual = QueryBuilder.queryFor(UserType.class, getPrismContext()) .item(UserType.F_LOCALITY).eq("Caribbean") .or() .not().item(UserType.F_DESCRIPTION).eq("desc") .and().all() .and().none() .or() .undefined() .and().not().none() .build(); ObjectQuery expected = ObjectQuery.createObjectQuery( OrFilter.createOr( createEqual(UserType.F_LOCALITY, UserType.class, null, "Caribbean"), AndFilter.createAnd( NotFilter.createNot( createEqual(UserType.F_DESCRIPTION, UserType.class, null, "desc") ), AllFilter.createAll(), NoneFilter.createNone() ), AndFilter.createAnd( UndefinedFilter.createUndefined(), NotFilter.createNot( NoneFilter.createNone() ) ) ) ); compare(actual, expected); } @Test public void test140TypeWithEquals() throws Exception{ ObjectQuery actual = QueryBuilder.queryFor(UserType.class, getPrismContext()) .type(UserType.class) .item(UserType.F_LOCALITY).eq("Caribbean") .build(); ObjectQuery expected = ObjectQuery.createObjectQuery( TypeFilter.createType( USER_TYPE_QNAME, createEqual(UserType.F_LOCALITY, UserType.class, null, "Caribbean") ) ); compare(actual, expected); } @Test public void test142TypeWithEqualsInBlock() throws Exception{ ObjectQuery actual = QueryBuilder.queryFor(UserType.class, getPrismContext()) .type(UserType.class) .block() .item(UserType.F_LOCALITY).eq("Caribbean") .endBlock() .build(); ObjectQuery expected = ObjectQuery.createObjectQuery( TypeFilter.createType( USER_TYPE_QNAME, createEqual(UserType.F_LOCALITY, UserType.class, null, "Caribbean") ) ); compare(actual, expected); } @Test public void test144TypeWithEqualsAndAllInBlock() throws Exception{ ObjectQuery actual = QueryBuilder.queryFor(UserType.class, getPrismContext()) .type(UserType.class) .block() .item(UserType.F_LOCALITY).eq("Caribbean") .and().all() .endBlock() .build(); ObjectQuery expected = ObjectQuery.createObjectQuery( TypeFilter.createType( USER_TYPE_QNAME, AndFilter.createAnd( createEqual(UserType.F_LOCALITY, UserType.class, null, "Caribbean"), AllFilter.createAll() ) ) ); compare(actual, expected); } @Test public void test144TypeInTypeInType() throws Exception{ ObjectQuery actual = QueryBuilder.queryFor(UserType.class, getPrismContext()) .type(UserType.class) .type(AssignmentType.class) .type(UserType.class) .all() .build(); ObjectQuery expected = ObjectQuery.createObjectQuery( TypeFilter.createType( USER_TYPE_QNAME, TypeFilter.createType( ASSIGNMENT_TYPE_QNAME, TypeFilter.createType( USER_TYPE_QNAME, AllFilter.createAll() ) ) ) ); compare(actual, expected); } @Test public void test146TypeAndSomething() throws Exception{ ObjectQuery actual = QueryBuilder.queryFor(UserType.class, getPrismContext()) .type(UserType.class) .none() .and().all() .build(); ObjectQuery expected = ObjectQuery.createObjectQuery( AndFilter.createAnd( TypeFilter.createType( USER_TYPE_QNAME, NoneFilter.createNone() ), AllFilter.createAll() ) ); compare(actual, expected); } @Test public void test148TypeEmpty() throws Exception{ ObjectQuery actual = QueryBuilder.queryFor(UserType.class, getPrismContext()) .type(UserType.class) .block().endBlock() .build(); ObjectQuery expected = ObjectQuery.createObjectQuery( TypeFilter.createType( USER_TYPE_QNAME, null ) ); compare(actual, expected); } @Test public void test149TypeEmptyAndAll() throws Exception{ ObjectQuery actual = QueryBuilder.queryFor(UserType.class, getPrismContext()) .type(UserType.class) .block().endBlock() .and().all() .build(); ObjectQuery expected = ObjectQuery.createObjectQuery( AndFilter.createAnd( TypeFilter.createType( USER_TYPE_QNAME, null ), AllFilter.createAll() ) ); compare(actual, expected); } @Test public void test150ExistsWithEquals() throws Exception{ ObjectQuery actual = QueryBuilder.queryFor(UserType.class, getPrismContext()) .exists(UserType.F_ASSIGNMENT) .item(AssignmentType.F_DESCRIPTION).startsWith("desc1") .build(); ComplexTypeDefinition assCtd = getPrismContext().getSchemaRegistry().findComplexTypeDefinitionByCompileTimeClass(AssignmentType.class); PrismContainerDefinition userPcd = getPrismContext().getSchemaRegistry().findContainerDefinitionByCompileTimeClass(UserType.class); ObjectQuery expected = ObjectQuery.createObjectQuery( ExistsFilter.createExists( new ItemPath(UserType.F_ASSIGNMENT), userPcd, SubstringFilter.createSubstring( new ItemPath(AssignmentType.F_DESCRIPTION), assCtd.findPropertyDefinition(AssignmentType.F_DESCRIPTION), getPrismContext(), null, "desc1", true, false) ) ); compare(actual, expected); } @Test public void test151ExistsWithEquals2() throws Exception{ ObjectQuery actual = QueryBuilder.queryFor(UserType.class, getPrismContext()) .exists(UserType.F_ASSIGNMENT) .item(AssignmentType.F_NOTE).endsWith("DONE.") .build(); ComplexTypeDefinition assCtd = getPrismContext().getSchemaRegistry().findComplexTypeDefinitionByCompileTimeClass(AssignmentType.class); PrismContainerDefinition userPcd = getPrismContext().getSchemaRegistry().findContainerDefinitionByCompileTimeClass(UserType.class); ObjectQuery expected = ObjectQuery.createObjectQuery( ExistsFilter.createExists( new ItemPath(UserType.F_ASSIGNMENT), userPcd, SubstringFilter.createSubstring( new ItemPath(AssignmentType.F_NOTE), assCtd.findPropertyDefinition(AssignmentType.F_NOTE), getPrismContext(), null, "DONE.", false, true) ) ); compare(actual, expected); } @Test public void test152ExistsWithEqualsInBlock() throws Exception{ ObjectQuery actual = QueryBuilder.queryFor(UserType.class, getPrismContext()) .exists(UserType.F_ASSIGNMENT) .block() .item(AssignmentType.F_NOTE).endsWith("DONE.") .endBlock() .build(); ComplexTypeDefinition assCtd = getPrismContext().getSchemaRegistry().findComplexTypeDefinitionByCompileTimeClass(AssignmentType.class); PrismContainerDefinition userPcd = getPrismContext().getSchemaRegistry().findContainerDefinitionByCompileTimeClass(UserType.class); ObjectQuery expected = ObjectQuery.createObjectQuery( ExistsFilter.createExists( new ItemPath(UserType.F_ASSIGNMENT), userPcd, SubstringFilter.createSubstring( new ItemPath(AssignmentType.F_NOTE), assCtd.findPropertyDefinition(AssignmentType.F_NOTE), getPrismContext(), null, "DONE.", false, true) ) ); compare(actual, expected); } @Test public void test154ExistsWithEqualsAndAllInBlock() throws Exception{ ObjectQuery actual = QueryBuilder.queryFor(UserType.class, getPrismContext()) .exists(UserType.F_ASSIGNMENT) .block() .item(AssignmentType.F_NOTE).endsWith("DONE.") .and().all() .endBlock() .build(); ComplexTypeDefinition assCtd = getPrismContext().getSchemaRegistry().findComplexTypeDefinitionByCompileTimeClass(AssignmentType.class); PrismContainerDefinition userPcd = getPrismContext().getSchemaRegistry().findContainerDefinitionByCompileTimeClass(UserType.class); ObjectQuery expected = ObjectQuery.createObjectQuery( ExistsFilter.createExists( new ItemPath(UserType.F_ASSIGNMENT), userPcd, AndFilter.createAnd( SubstringFilter.createSubstring( new ItemPath(AssignmentType.F_NOTE), assCtd.findPropertyDefinition(AssignmentType.F_NOTE), getPrismContext(), null, "DONE.", false, true ), AllFilter.createAll() ) ) ); compare(actual, expected); } @Test public void test156ExistsAndSomething() throws Exception{ ObjectQuery actual = QueryBuilder.queryFor(UserType.class, getPrismContext()) .exists(UserType.F_ASSIGNMENT) .none() .and().all() .build(); ComplexTypeDefinition assCtd = getPrismContext().getSchemaRegistry().findComplexTypeDefinitionByCompileTimeClass(AssignmentType.class); PrismContainerDefinition userPcd = getPrismContext().getSchemaRegistry().findContainerDefinitionByCompileTimeClass(UserType.class); ObjectQuery expected = ObjectQuery.createObjectQuery( AndFilter.createAnd( ExistsFilter.createExists( new ItemPath(UserType.F_ASSIGNMENT), userPcd, NoneFilter.createNone() ), AllFilter.createAll() ) ); compare(actual, expected); } @Test public void test200OrderByName() throws Exception{ ObjectQuery actual = QueryBuilder.queryFor(UserType.class, getPrismContext()) .asc(UserType.F_NAME) .build(); ObjectQuery expected = ObjectQuery.createObjectQuery( ObjectPaging.createPaging(UserType.F_NAME, OrderDirection.ASCENDING) ); compare(actual, expected); } @Test public void test210OrderByNameAndId() throws Exception{ ObjectQuery actual = QueryBuilder.queryFor(UserType.class, getPrismContext()) .item(UserType.F_LOCALITY).eq("Caribbean") .asc(UserType.F_NAME) .desc(PrismConstants.T_ID) .build(); ObjectPaging paging = ObjectPaging.createEmptyPaging(); paging.addOrderingInstruction(UserType.F_NAME, OrderDirection.ASCENDING); paging.addOrderingInstruction(PrismConstants.T_ID, OrderDirection.DESCENDING); ObjectQuery expected = ObjectQuery.createObjectQuery( createEqual(UserType.F_LOCALITY, UserType.class, null, "Caribbean"), paging); compare(actual, expected); } @Test public void test300EqualItem() throws Exception { ObjectQuery actual = QueryBuilder.queryFor(UserType.class, getPrismContext()) .item(UserType.F_LOCALITY).eq().item(UserType.F_NAME) .build(); PrismContainerDefinition userPcd = getPrismContext().getSchemaRegistry().findContainerDefinitionByCompileTimeClass(UserType.class); ObjectQuery expected = ObjectQuery.createObjectQuery( EqualFilter.createEqual( new ItemPath(UserType.F_LOCALITY), userPcd.findPropertyDefinition(UserType.F_LOCALITY), null, new ItemPath(UserType.F_NAME), null ) ); compare(actual, expected); } @Test public void test310LessThanItem() throws Exception { PrismObjectDefinition userDef = getSchemaRegistry().findObjectDefinitionByCompileTimeClass(UserType.class); PrismPropertyDefinition nameDef = userDef.findPropertyDefinition(UserType.F_NAME); PrismPropertyDefinition localityDef = userDef.findPropertyDefinition(UserType.F_LOCALITY); ObjectQuery actual = QueryBuilder.queryFor(UserType.class, getPrismContext()) .item(new ItemPath(UserType.F_LOCALITY), localityDef) .le() .item(new ItemPath(UserType.F_NAME), nameDef) .build(); ObjectQuery expected = ObjectQuery.createObjectQuery( LessFilter.createLess( new ItemPath(UserType.F_LOCALITY), localityDef, new ItemPath(UserType.F_NAME), nameDef, true ) ); compare(actual, expected); } protected void compare(ObjectQuery actual, ObjectQuery expected) { String exp = expected.debugDump(); String act = actual.debugDump(); System.out.println("Generated query:\n" + act); AssertJUnit.assertEquals("queries do not match", exp, act); } private <C extends Containerable, T> EqualFilter<T> createEqual(QName propertyName, Class<C> type, QName matchingRule, T realValue) { return createEqual(new ItemPath(propertyName), type, matchingRule, realValue); } private <C extends Containerable, T> EqualFilter<T> createEqual(ItemPath propertyPath, Class<C> type, QName matchingRule, T realValue) { PrismPropertyDefinition<T> propertyDefinition = (PrismPropertyDefinition) FilterUtils.findItemDefinition(propertyPath, type, getPrismContext()); return EqualFilter.createEqual(propertyPath, propertyDefinition, matchingRule, getPrismContext(), realValue); } }