/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.testing.tests.queries;

import java.util.*;

import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.testing.models.employee.domain.*;
import org.eclipse.persistence.testing.models.employee.domain.Project;
import org.eclipse.persistence.sessions.*;
import org.eclipse.persistence.expressions.*;
import org.eclipse.persistence.queries.*;
import org.eclipse.persistence.sessions.Record;
import org.eclipse.persistence.testing.framework.*;
import org.eclipse.persistence.testing.tests.clientserver.*;
import org.eclipse.persistence.tools.schemaframework.PopulationManager;

public class QueryFrameworkTestSuite extends TestSuite {
    public QueryFrameworkTestSuite() {
        setDescription("This suite tests all of the functionality of the query framework.");
    }

    public QueryFrameworkTestSuite(boolean isSRG) {
        super(isSRG);
        setDescription("This suite tests all of the functionality of the query framework.");
    }

    @Override
    public void addTests() {
        addSRGTests();
        addTest(new QueryTimeoutTest());
        //Add new tests here, if any.
        addTest(new ServerSessionTestAdapter(new PessimisticLockNoLockJoinedTest()));
        addTest(new ReadAllNoDistinctTest());
        addTest(new ObjectLevelReadQueryTest.CustomQueryRaceConditionsInReadAllQueryTest());
        addTest(new ObjectLevelReadQueryTest.CustomQueryRaceConditionsInReadObjectQueryTest());
        addTest(new PartialAttributeTestWithJoinAttribute());
        addTest(new PartialAttributeDistinctOrderByTest());
        addTest(new FourPartialAttributeTestsWithJoinAttribute());
        addTest(buildReadOnlyQueryTest());
        addTest(buildGetSQLTest());
        addTest(buildJoinSubclassesQueryTest());
        addTest(buildRecordTest());
        // Bug 6450867 - TOPLINK-6069 ON READOBJECTQUERY ON ENTITY USING MULTIPLE TABLE MAPPING
        addTest(new ConformResultsWithMultitableAndJoiningTest());
        // EL Bug 235484 - EclipseLink is holding onto old unit of work
        addTest(new CachedUpdateCallsQueryClearTest());
        addTest(new ZeroPrimaryKeyExistenceCheckTest(true));
        addTest(new ZeroPrimaryKeyExistenceCheckTest(false));
        // EL Bug 244241 - connection not released on query timeout when cursor used
        addTest(new QueryTimeoutConnectionReleasedTest());
        // EL Bug 245448 - Add regression tests for querying across  relationships using nested
        // joining and DailyCacheInvalidationPolicy
        addTest(new QueryExecutionTimeSetOnBuildObjectTest());
        // EL Bug 245986 - Add regression testing for queries using custom SQL and partial attribute population
        addTest(new PartialAttributeWithCustomSQLTest());
        addTest(buildArgumentValuesTest());
        addTest(new ScrollableCursorForwardOnlyResultSetTest()); // Bug 309142
        addTest(new ConformResultsSubclassesTest()); // Bug 327900
        addTest(new ScrollableCursorJoinedAttributeTest()); // Bug 351509
        addTest(new ScrollableCursorJoiningVerificationTest()); // Bug 361860
        addTest(new MultipleOrderByWithSameFieldNameNullsFirstTest());
        addTest(new MultipleOrderByWithSameFieldNameTest());
        addTest(buildUnionTest());
    }

    //SRG test set is maintained by QA only, do NOT add any new test cases into it.
    @Override
    public void addSRGTests() {
        ReadAllQuery raq2 = new ReadAllQuery();
        raq2.setReferenceClass(Employee.class);
        raq2.useCollectionClass(ArrayList.class);
        addTest(new CollectionReadAllTest(Employee.class, 12, raq2));

        ReadAllQuery raq3 = new ReadAllQuery();
        raq3.setReferenceClass(Employee.class);
        raq3.useCollectionClass(Vector.class);
        addTest(new CollectionReadAllTest(Employee.class, 12, raq3));

        ReadAllQuery raq4 = new ReadAllQuery();
        raq4.setReferenceClass(Employee.class);
        raq4.useCollectionClass(HashSet.class);
        addTest(new CollectionReadAllTest(Employee.class, 12, raq4));

        ReadAllQuery raq6 = new ReadAllQuery();
        raq6.setReferenceClass(Employee.class);
        raq6.useMapClass(HashMap.class, "getFirstName");
        addTest(new CollectionReadAllTest(Employee.class, 12, raq6));

        ReadAllQuery raq9 = new ReadAllQuery();
        raq9.setReferenceClass(Employee.class);
        raq9.useMapClass(Hashtable.class, "getId");
        addTest(new CollectionReadAllTest(Employee.class, 12, raq9));

        ReadAllQuery raq10 = new ReadAllQuery();
        raq10.setReferenceClass(Employee.class);
        raq10.useCollectionClass(ArrayList.class);
        addTest(new CollectionReadAllTest(Employee.class, 12, raq10));

        ReadAllQuery raq20 = new ReadAllQuery();
        raq20.setReferenceClass(Employee.class);
        raq20.useMapClass(Hashtable.class, "getFirstName");
        addTest(new MapReadAllTest(Employee.class, 12, raq20));

        ReadAllQuery raq21 = new ReadAllQuery();
        raq21.setReferenceClass(Employee.class);
        raq21.useMapClass(TreeMap.class, "getId");
        addTest(new MapReadAllTest(Employee.class, 12, raq21));

        addTest(new RefreshNoCacheWithNoIdentityMapTest());
        addTest(new ShallowModifyTest());
        addTest(new DontMaintainCacheTest());
        addTest(new CursoredStreamTest(Employee.class, new org.eclipse.persistence.expressions.ExpressionBuilder().get("address").get("city").equal("Ottawa")));
        addTest(new CursoredStreamTest(Employee.class, new org.eclipse.persistence.expressions.ExpressionBuilder().get("firstName").like("B%")));
        addTest(new CursoredStreamTest(LargeProject.class, new org.eclipse.persistence.expressions.ExpressionBuilder().get("teamLeader").get("firstName").like("Sarah%")));

        addTest(new CursoredStreamWithUselessConformTest(Employee.class, new org.eclipse.persistence.expressions.ExpressionBuilder().get("address").get("city").equal("Ottawa")));
        addTest(new CursoredStreamWithUselessConformTest(Employee.class, new org.eclipse.persistence.expressions.ExpressionBuilder().get("firstName").like("B%")));
        addTest(new CursoredStreamWithUselessConformTest(LargeProject.class, new org.eclipse.persistence.expressions.ExpressionBuilder().get("teamLeader").get("firstName").like("Sarah%")));

        addTest(new CursoredStreamCustomSQLTest());
        addTest(new CursoredStreamAnyOfTest());
        addTest(new CursoredStreamWithUnitOfWorkTest());
        addTest(new CursoredStreamDistinctTest());

        //addTest(new CursoredStreamReleaseConnectionsTest(Employee.class, new org.eclipse.persistence.expressions.ExpressionBuilder().get("address").get("city").equal("Ottawa")));
        addTest(new CursoredStreamReleaseConnectionsTest(false));
        addTest(new CursoredStreamReleaseConnectionsTest(true));

        addTest(new ScrollableCursorTest(Employee.class, new org.eclipse.persistence.expressions.ExpressionBuilder().get("firstName").like("B%")));
        addTest(new ScrollableCursorTest(LargeProject.class, new org.eclipse.persistence.expressions.ExpressionBuilder().get("teamLeader").get("firstName").like("Sarah%")));
        addTest(new ScrollableCursorAPITest());
        addTest(new ScrollableCursorBackwardReadingTest());
        addTest(new ScrollableCursorStatementCachingReadTest());
        addTest(new ScrollableCursorNavigationAPITest());

        // Cursor conforming tests...
        addTest(new CursoredStreamConformingTest());
        addTest(new CursoredStreamConformingTest(true));
        addTest(new ScrollableCursorBackwardReadingTest(true));
        addTest(new ScrollableCursorNavigationAPITest(true));

        addTest(new OrderingTest());
        addTest(new OrderingMutipleTableTest());
        addTest(new OrderingSuperClassTest());
        addTest(new OrderingByExpressionTest());
        addTest(new OrderingWithAnyOfTest());
        addTest(new ShallowRefreshTest());
        addTest(new RefreshTest());
        addTest(new PessimisticLockTest(ObjectLevelReadQuery.LOCK));
        addTest(new PessimisticLockTest(ObjectLevelReadQuery.LOCK_NOWAIT));
        addTest(new PessimisticLockFineGrainedTest(ObjectLevelReadQuery.LOCK_NOWAIT));
        addTest(new PessimisticLockOutsideUnitOfWorkTest(ObjectLevelReadQuery.LOCK_NOWAIT));
        addTest(new PessimisticLockInheritanceTest(ObjectLevelReadQuery.LOCK_NOWAIT));
        addTest(new ServerSessionTestAdapter(new PessimisticLockJoinedAttributeTest()));
        addTest(new ServerSessionTestAdapter(new PessimisticLockBatchAttributeTest()));
        addTest(new PessimisticLockEmptyTransactionTest());
        addTest(new PessimisticLockIndirectionJoiningTest(ObjectLevelReadQuery.LOCK_NOWAIT));
        addTest(new PessimisticLockRefreshTest(ObjectLevelReadQuery.LOCK_NOWAIT));
        addTest(new OnlyRefreshIfNewTest());
        addTest(new DeepRefreshTest());
        addTest(new PredefinedQueryReadAllTest(Employee.class, 12));
        addTest(new PredefinedInQueryReadAllTest(Employee.class, 1));
        addTest(new PredefinedQueryReadObjectTest(PopulationManager.getDefaultManager().getObject(Employee.class, "0001")));
        addTest(new PredefinedQueryLikeIgnoreCaseTest());
        addTest(buildPredefinedObjectComparisonTest());
        addTest(buildPredefinedInTest());
        addTest(buildPredefinedEqualNullTest());
        addTest(buildPredefinedContainsSubStringTest());
        addTest(buildPredefinedAnyOfObjectComparisonTest());
        addTest(buildPredefinedObjectTypeTest());
        addTest(buildPredefinedNestedParameterTest());
        addTest(buildPredefinedRedirectorTest());
        addTest(buildPredefinedMethodRedirectorTest());
        addTest(new PredefinedQueryInheritanceTest());
        addTest(new PredefinedQueryToUpperOnParameterTest(PopulationManager.getDefaultManager().getObject(Employee.class, "0001")));
        addTest(new ReloadSelectionObjectTest(new EmployeePopulator().basicEmployeeExample1(), true));
        addTest(new ReloadSelectionObjectTest(new EmployeePopulator().basicEmployeeExample1(), false));
        addTest(new BadQueryTest());
        addTest(new Jdk12ScrollableCursorTest());
        //Bug#2839852  Refreshing is not possible if the query uses checkCacheOnly.
        addTest(new RefreshWithCheckCacheOnlyTest());

        /** Test cascaded read queries */
        addTest(new CascadingAllCacheTest());
        addTest(new CascadingAllNoCacheTest());
        addTest(new CascadingNoneCacheTest());
        addTest(new CascadingNoneNoCacheTest());
        addTest(new CascadingPrivateCacheTest());
        addTest(new CascadingPrivateNoCacheTest());

        /** Test cascaded modify queries */
        addTest(new DeepModifyTest());
        addTest(new PrivateModifyTest());

        /** Test cascaded delete queries */
        addTest(new DeepDeleteTest());
        addTest(new PrivateDeleteTest());
        addTest(new DoesExistTest());
        addTest(new DataReadQueryTest1());
        addTest(new DirectReadQueryTest1());
        addTest(new ValueReadQueryTest1());

        addTest(new GetValueFromObject());
        addTest(new CursoredStreamClientSessionTest());
        addTest(new CursoredStreamReadWriteClientSessionTest());

        addTest(new QBEObjectWithAllFieldsFilled());
        addTest(new QBESpecialOperators());
        addTest(new QBEExcludedValues());
        addTest(new QBEValidateUnsupportedMappingsFlag());
        addTest(new QBEObjectReferenceMapping());
        addTest(new QBECollectionMapping());

        // Conforming tests
        // For bug 3568141: shoudn't ignore policy if set to triggerIndirection()
        addTest(new ConformingShouldTriggerIndirectionTest());
        // For bug 3570561: shouldn't throw valueholder exceptions
        addTest(new ConformingThrowConformExceptionsTest());
        addTest(new ConformResultsAcrossOneToOneTest(ConformResultsAcrossOneToOneTest.EQUAL));
        addTest(new ConformResultsAcrossOneToOneTest(ConformResultsAcrossOneToOneTest.NOT_EQUAL));
        addTest(new ConformResultsAcrossOneToOneTest(ConformResultsAcrossOneToOneTest.IS_NULL));
        addTest(new ConformResultsAcrossOneToOneTest(ConformResultsAcrossOneToOneTest.NOT_NULL));
        // Added for bug 3324757: REDIRECT QUERY RESULTS DO NOT CONFORM TO A UNITOFWORK
        addTest(new ConformResultsRedirectorTest());
        addTest(new ConformResultsWithSelectionObjectTest());
        // Added for bug 2782991: Conforming find by primary key takes linear time.
        addTests(ConformResultsWithPrimaryKeyExpressionTest.buildTests());
        addTest(new ConformResultsAcrossOneToManyAcrossOneToOneTest());
        addTest(new ConformResultsAcrossOneToManyTest());
        addTest(new ConformResultsAcrossWrappedOneToManyTest());
        addTest(new ShouldRegisterResultsInUnitOfWorkTest(false));
        addTest(new ShouldRegisterResultsInUnitOfWorkTest(true));
        addTest(new ConformResultsPerformanceTest());

        addTest(new OneToManyMaxRowsSettingTest());

        // Created for BUG# 2745106
        addTest(new QueryExceptionStringTest());
        addTest(new NamedQueriesClientSessionTest());
        addTest(new NamedQueriesDescriptorQueryManagerTest());
        addTest(new NamedQueriesUOWTest());
        addTest(new NamedQueryGetQueryNoArgumentsTest());
        addTest(new ServerClientNamedQueryTest());
        addTest(new GetTableGetFieldTest());
        //code coverage
        addTest(new NamedQueryNotFoundInUOWTest());

        // Created for CR# 4286
        addTest(new DeleteAllQueryTest());

        // Created for bug 5840824
        addTest(new DeleteObjectPrivatelyOwningUntriggeredIndirection());

        // Created for BUG# 2692956
        addTest(new RedirectQueryOnUOWTest());
        addTest(new RedirectorOnDescriptorTest());

        addTest(new DoNotRedirectDefaultRedirectorTest());

        //created for BUG# 3037982
        addTest(new SetReferenceClassTest());

        // Created for BUG# 3136413
        addTest(new QueryByExampleInUOWTest());

        addTest(new InheritancePrepareTest());
        addTest(new InheritanceViewPrepareTest());

        // Create for BUG# 3337003
        addTest(new DataReadQueryContainerPolicyTest());

        // New tests added for the UpdateAllQuery feature work
        addTest(new UpdateAllQueryTest());
        addTest(new UpdateAllQueryUOWTest());
        addTest(new UpdateAllQueryUOWTest(false));
        addTest(new UpdateAllQueryExpressionMathTest());
        addTest(new UpdateAllQueryRollbackTest());

        addTest(new UOWgetQueryTest());
        addTest(new CascadeNoBindingOnQuery());
        addTest(new IncorrectPartialAttributeTest());

        addTest(new FirstResultAndMaxRowsTest(0, 0, 12));
        addTest(new FirstResultAndMaxRowsTest(1, 0, 11));
        addTest(new FirstResultAndMaxRowsTest(0, 5, 5));
        addTest(new FirstResultAndMaxRowsTest(2, 5, 3));

        addTest(new QueryCacheTest());

        // Created for Bug 4318924
        addTest(new TranslatedStringsTest());

    }

    /**
     * Test the read-only query feature.
     */
    public TestCase buildReadOnlyQueryTest() {
        TestCase test = new TestCase() {
            @Override
            public void test() {
                UnitOfWork uow = getSession().acquireUnitOfWork();
                // Test read alls.
                ReadAllQuery query = new ReadAllQuery(Employee.class);
                query.setIsReadOnly(true);
                List result = (List) uow.executeQuery(query);
                if (uow.isObjectRegistered(result.get(0))) {
                    throwError("Read-only result was registered.");
                }
                // Test read objects.
                ReadObjectQuery objectQuery = new ReadObjectQuery(result.get(0));
                objectQuery.setIsReadOnly(true);
                Employee employee = (Employee)uow.executeQuery(objectQuery);
                if (uow.isObjectRegistered(employee)) {
                    throwError("Read-only result was registered.");
                }
                if (employee != result.get(0)) {
                    throwError("Read-only result identity not maintained.");
                }
                // Test object works.
                employee.getAddress();
            }
        };
        test.setName("ReadOnlyQueryTest");
        return test;
    }

    /**
     * Test unions.
     */
    public TestCase buildUnionTest() {
        TestCase test = new TestCase() {
            @Override
            public void setup() {
                if (getSession().getPlatform().isMySQL() || getSession().getPlatform().isSybase() || getSession().getPlatform().isSymfoware() ) {
                    throwWarning("Database does not support INTERSECT");
                }
            }

            @Override
            public void test() {
                ExpressionBuilder e = new ExpressionBuilder();
                ReadAllQuery query = new ReadAllQuery(Employee.class, e);
                query.setSelectionCriteria(e.get("firstName").equal("Bob"));

                ExpressionBuilder e2 = new ExpressionBuilder();
                ReportQuery union = new ReportQuery(Employee.class, e2);
                union.addItem("employee", e2);
                union.setSelectionCriteria(e2.get("firstName").equal("Sarah"));
                query.union(union);

                ExpressionBuilder e3 = new ExpressionBuilder();
                ReportQuery unionAll = new ReportQuery(Employee.class, e3);
                unionAll.addItem("employee", e3);
                unionAll.setSelectionCriteria(e3.get("firstName").equal("Sarah"));
                query.addUnionExpression(e.unionAll(e.subQuery(unionAll)));

                ExpressionBuilder e4 = new ExpressionBuilder();
                ReportQuery intersect = new ReportQuery(Employee.class, e4);
                intersect.addItem("employee", e4);
                intersect.setSelectionCriteria(e4.get("firstName").equal("Sarah"));
                query.intersect(intersect);

                /*ExpressionBuilder e5 = new ExpressionBuilder();
                ReportQuery intersectAll = new ReportQuery(Employee.class, e5);
                intersectAll.addItem("employee", e5);
                intersectAll.setSelectionCriteria(e5.get("firstName").equal("Sarah"));
                query.addUnionExpression(e.intersectAll(e.subQuery(intersectAll)));*/

                ExpressionBuilder e6 = new ExpressionBuilder();
                ReportQuery except = new ReportQuery(Employee.class, e6);
                except.addItem("employee", e6);
                except.setSelectionCriteria(e6.get("firstName").equal("Sarah"));
                query.except(except);

                /*ExpressionBuilder e7 = new ExpressionBuilder();
                ReportQuery exceptAll = new ReportQuery(Employee.class, e7);
                exceptAll.addItem("employee", e7);
                exceptAll.setSelectionCriteria(e7.get("firstName").equal("Sarah"));
                query.addUnionExpression(e.exceptAll(e.subQuery(exceptAll)));*/

                List result = (List)getSession().executeQuery(query);
                if (result.size() > 0) {
                    throwError("Expected 0 elements: " + result);
                }
            }
        };
        test.setName("UnionTest");
        return test;
    }

    /**
     * Query argument values.
     */
    public TestCase buildArgumentValuesTest() {
        TestCase test = new TestCase() {
            @Override
            public void test() {
                // Test read alls.
                ReadAllQuery query = new ReadAllQuery(Employee.class);
                query.setSelectionCriteria(query.getExpressionBuilder().get("firstName").equal(
                        query.getExpressionBuilder().getParameter("firstName")));
                query.addArgument("firstName");
                query.addArgumentValue("Bob");
                List<Employee> result = (List) getSession().executeQuery(query);
                for (Employee employee : result) {
                    if (!employee.getFirstName().equals("Bob")) {
                        throwError("Incorrect result: " + employee);
                    }
                }
            }
        };
        test.setName("ArgumentValuesTest");
        return test;
    }

    /**
     * Test getting the SQL for a parameterized query.
     */
    public TestCase buildGetSQLTest() {
        TestCase test = new TestCase() {
            @Override
            public void test() {
                ReadAllQuery query = new ReadAllQuery(Employee.class);
                ExpressionBuilder builder = query.getExpressionBuilder();
                query.setSelectionCriteria(builder.get("firstName").equal(builder.getParameter("name")));
                query.addArgument("name");
                Record record = new DatabaseRecord();
                record.put("name", "Bob");
                String sql = query.getTranslatedSQLString(getSession(), record);
                if (sql.indexOf("?") != -1) {
                    throwError("SQL was not translated.");
                }
            }
        };
        test.setName("GetSQLTest");
        return test;
    }

    /**
     * Test the join-subclasses query feature.
     */
    public TestCase buildJoinSubclassesQueryTest() {
        TestCase test = new TestCase() {
            @Override
            public void test() {
                UnitOfWork uow = getSession().acquireUnitOfWork();
                ReadAllQuery query = new ReadAllQuery(Project.class);
                boolean TYPE_SCROLL_INSENSITIVE_isSupported = true;
                boolean CONCUR_UPDATABLE_isSupported = true;
                if(getSession().getPlatform().isSQLServer()) {
                    // In case either TYPE_SCROLL_INSENSITIVE or CONCUR_UPDATABLE used
                    // MS SQL Server  Version: 9.00.2050;  MS SQL Server 2005 JDBC Driver  Version: 1.2.2828.100 throws exception:
                    // com.microsoft.sqlserver.jdbc.SQLServerException: The cursor type/concurrency combination is not supported.
                    TYPE_SCROLL_INSENSITIVE_isSupported = false;
                    CONCUR_UPDATABLE_isSupported = false;
                }
                if(getSession().getPlatform().isSymfoware()) {
                    // Symfoware supports updatable cursors, but not in this way. Also,
                    // it considers SQL queries that select from multiple tables as
                    // non-updatable, thus raising an exception for this test.
                    TYPE_SCROLL_INSENSITIVE_isSupported = false;
                    CONCUR_UPDATABLE_isSupported = false;
                }
                // HANA supports only TYPE_FORWARD_ONLY and CONCUR_READ_ONLY, see bug 384116
                if (getSession().getPlatform().isHANA()) {
                    ScrollableCursorPolicy policy = new ScrollableCursorPolicy();
                    policy.setResultSetType(ScrollableCursorPolicy.TYPE_FORWARD_ONLY);
                    policy.setResultSetConcurrency(ScrollableCursorPolicy.CONCUR_READ_ONLY);
                    policy.setPageSize(10);
                    query.useScrollableCursor(policy);
                } else if(TYPE_SCROLL_INSENSITIVE_isSupported && CONCUR_UPDATABLE_isSupported) {
                    query.useScrollableCursor();
                } else {
                    ScrollableCursorPolicy policy = new ScrollableCursorPolicy();
                    if(!TYPE_SCROLL_INSENSITIVE_isSupported) {
                        policy.setResultSetType(ScrollableCursorPolicy.TYPE_SCROLL_SENSITIVE);
                    }
                    if(!CONCUR_UPDATABLE_isSupported) {
                        policy.setResultSetConcurrency(ScrollableCursorPolicy.CONCUR_READ_ONLY);
                    }
                    policy.setPageSize(10);
                    query.useScrollableCursor(policy);
                }
                query.setShouldOuterJoinSubclasses(true);
                Cursor result = (Cursor) uow.executeQuery(query);
                result.nextElement();
                result.close();
            }
        };
        test.setName("JoinSubclassesQueryTest");
        return test;
    }

    public PredefinedQueryTest buildPredefinedAnyOfObjectComparisonTest() {
        Employee employee = (Employee)PopulationManager.getDefaultManager().getObject(Employee.class, "0002");

        ReadObjectQuery query = new ReadObjectQuery(Employee.class);
        query.setName("findEmployeeByPhone");
        query.setSelectionCriteria(query.getExpressionBuilder().anyOf("phoneNumbers").equal(query.getExpressionBuilder().getParameter("phone")));
        query.addArgument("phone");

        Vector arguments = new Vector();
        arguments.addElement(employee.getPhoneNumbers().firstElement());

        PredefinedQueryTest test = new PredefinedQueryTest(query, employee, arguments);
        test.setName("PredefinedAnyOfObjectComparisonTest");
        test.setDescription("Test that any of object comparisons can be parameterized.");

        return test;
    }

    public PredefinedQueryTest buildPredefinedContainsSubStringTest() {
        Employee employee = (Employee)PopulationManager.getDefaultManager().getObject(Employee.class, "0002");

        ReadObjectQuery query = new ReadObjectQuery(Employee.class);
        query.setName("findEmployeeWithNameContaining");
        query.setSelectionCriteria(query.getExpressionBuilder().get("firstName").containsSubstringIgnoringCase(query.getExpressionBuilder().getParameter("name")));
        query.addArgument("name");

        Vector arguments = new Vector();
        arguments.addElement(employee.getFirstName().toLowerCase());

        PredefinedQueryTest test = new PredefinedQueryTest(query, employee, arguments);
        test.setName("PredefinedContainsSubStringTest");
        test.setDescription("Test that complex function can be parameterized.");

        return test;
    }

    public PredefinedQueryTest buildPredefinedEqualNullTest() {
        ReadObjectQuery query = new ReadObjectQuery(Employee.class);
        query.setName("findEmployeeByName");
        query.setSelectionCriteria(query.getExpressionBuilder().get("firstName").equal(query.getExpressionBuilder().getParameter("name")));
        query.addArgument("name");
        query.setShouldPrepare(false);

        Vector arguments = new Vector();
        arguments.addElement(null);

        PredefinedQueryTest test = new PredefinedQueryTest(query, null, arguments);
        test.setName("PredefinedEqualNullTest");
        test.setDescription("Test that equal null can be parameterized.");

        return test;
    }

    public PredefinedQueryTest buildPredefinedInTest() {
        Employee employee = (Employee)PopulationManager.getDefaultManager().getObject(Employee.class, "0002");

        ReadObjectQuery query = new ReadObjectQuery(Employee.class);
        query.setName("findEmployeeByName");
        query.setSelectionCriteria(query.getExpressionBuilder().get("firstName").in(query.getExpressionBuilder().getParameter("names")));
        query.addArgument("names");
        query.setShouldPrepare(false);
        query.bindAllParameters();

        Vector arguments = new Vector();
        Vector names = new Vector();
        names.addElement(employee.getFirstName());
        names.addElement("Hommer-Simpson");
        arguments.addElement(names);

        PredefinedQueryTest test = new PredefinedQueryTest(query, employee, arguments);
        test.setName("PredefinedInTest");
        test.setDescription("Test that in's can be parameterized.");

        return test;
    }

    public PredefinedQueryTest buildPredefinedMethodRedirectorTest() {
        final Employee employee = (Employee)PopulationManager.getDefaultManager().getObject(Employee.class, "0002");

        ReadObjectQuery query = new ReadObjectQuery(Employee.class);
        query.setName("findEmployeeByAnEmployee");
        query.addArgument("employee");
        MethodBaseQueryRedirector redirector = new MethodBaseQueryRedirector(QueryFrameworkTestSuite.class, "findEmployeeByAnEmployee");
        query.setRedirector(redirector);
        Vector arguments = new Vector();
        arguments.addElement(employee);

        PredefinedQueryTest test = new PredefinedQueryTest(query, employee, arguments);
        test.setName("PredefinedMethodRedirectorTest");
        test.setDescription("Test query redirectors.");

        return test;
    }

    public PredefinedQueryTest buildPredefinedNestedParameterTest() {
        Employee employee = (Employee)PopulationManager.getDefaultManager().getObject(Employee.class, "0002");

        ReadObjectQuery query = new ReadObjectQuery(Employee.class);
        query.setName("findEmployeeInSameCity");
        query.setSelectionCriteria(query.getExpressionBuilder().get("address").get("city").equal(query.getExpressionBuilder().getParameter("employee").get("address").get("city")));
        query.addArgument("employee");

        Vector arguments = new Vector();
        arguments.addElement(employee);

        PredefinedQueryTest test = new PredefinedQueryTest(query, employee, arguments);
        test.setName("PredefinedNestedParameterTest");
        test.setDescription("Test nested parameters.");

        return test;
    }

    public PredefinedQueryTest buildPredefinedObjectComparisonTest() {
        Employee employee = (Employee)PopulationManager.getDefaultManager().getObject(Employee.class, "0002");

        ReadObjectQuery query = new ReadObjectQuery(Employee.class);
        query.setName("findEmployeeByAddress");
        query.setSelectionCriteria(query.getExpressionBuilder().get("address").equal(query.getExpressionBuilder().getParameter("address")));
        query.addArgument("address");

        Vector arguments = new Vector();
        arguments.addElement(employee.getAddress());

        PredefinedQueryTest test = new PredefinedQueryTest(query, employee, arguments);
        test.setName("PredefinedObjectComparisonTest");
        test.setDescription("Test that object comparisons can be parameterized.");

        return test;
    }

    public PredefinedQueryTest buildPredefinedObjectTypeTest() {
        Employee employee = (Employee)PopulationManager.getDefaultManager().getObject(Employee.class, "0002");

        ReadObjectQuery query = new ReadObjectQuery(Employee.class);
        query.setName("findEmployeeByGender");
        query.setSelectionCriteria(query.getExpressionBuilder().get("firstName").equal(query.getExpressionBuilder().getParameter("firstName")).and(query.getExpressionBuilder().get("gender").equal(query.getExpressionBuilder().getParameter("gender"))));
        query.addArgument("firstName");
        query.addArgument("gender");

        Vector arguments = new Vector();
        arguments.addElement(employee.getFirstName());
        arguments.addElement(employee.getGender());

        PredefinedQueryTest test = new PredefinedQueryTest(query, employee, arguments);
        test.setName("PredefinedObjectTypeTest");
        test.setDescription("Test that object type mappings can be parameterized.");

        return test;
    }

    public PredefinedQueryTest buildPredefinedRedirectorTest() {
        final Employee employee = (Employee)PopulationManager.getDefaultManager().getObject(Employee.class, "0002");

        ReadObjectQuery query = new ReadObjectQuery(Employee.class);
        query.setName("findEmployeeByEmployee");
        query.addArgument("employee");
        query.setRedirector(new QueryRedirector() {
                @Override
                public Object invokeQuery(DatabaseQuery query, org.eclipse.persistence.sessions.Record arguments, org.eclipse.persistence.sessions.Session session) {
                    return arguments.get("employee");
                }
            });

        Vector arguments = new Vector();
        arguments.addElement(employee);

        PredefinedQueryTest test = new PredefinedQueryTest(query, employee, arguments);
        test.setName("PredefinedRedirectorTest");
        test.setDescription("Test query redirectors.");

        return test;
    }

    /**
     * Test the record Map API.
     */
    public TestCase buildRecordTest() {
        TestCase test = new TestCase() {
            @Override
            public void test() {
                ReadAllQuery query = new ReadAllQuery(Employee.class);
                query.setShouldIncludeData(true);
                ComplexQueryResult result = (ComplexQueryResult) getSession().executeQuery(query);
                DatabaseRecord record = (DatabaseRecord)((List)result.getData()).get(0);
                Iterator keySetKeys = record.keySet().iterator();
                Iterator<DatabaseField> keys = record.getFields().iterator();
                while (keys.hasNext() || keySetKeys.hasNext()) {
                    if (keys.next() != keySetKeys.next()) {
                        throwError("KeySet is incorrect.");
                    }
                }
                Iterator valuesSetValues = record.values().iterator();
                Iterator values = record.getValues().iterator();
                while (values.hasNext() || valuesSetValues.hasNext()) {
                    if (values.next() != valuesSetValues.next()) {
                        throwError("ValuesSet is incorrect.");
                    }
                }
                Iterator entries = record.entrySet().iterator();
                keys = record.getFields().iterator();
                values = record.getValues().iterator();
                while (entries.hasNext() || keys.hasNext()) {
                    Map.Entry entry = (Map.Entry)entries.next();
                    if ((entry.getKey() != keys.next()) || (entry.getValue() != values.next())) {
                        throwError("EntrySet is incorrect.");
                    }
                }
            }
        };
        test.setName("BuildRecordTest");
        return test;
    }

    public static Object findEmployeeByAnEmployee(DatabaseQuery query, org.eclipse.persistence.sessions.DatabaseRecord arguments, org.eclipse.persistence.sessions.Session session) {
        ((ReadObjectQuery)query).setSelectionObject(arguments.get("employee"));

        return session.executeQuery(query);
    }

    public static Object findEmployeeByAnEmployee(org.eclipse.persistence.sessions.Session session, Vector arguments) {
        return arguments.firstElement();
    }
}
