/*
 * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/

/*
 * $Id: Client.java 66539 2012-06-27 12:26:24Z sdimilla $
 */
package com.sun.ts.tests.jpa.core.relationship.descriptors;

import com.sun.javatest.Status;
import com.sun.ts.lib.util.TestUtil;
import com.sun.ts.tests.jpa.common.PMClientBase;

import java.math.BigDecimal;
import java.util.Collection;
import java.util.Iterator;
import java.util.Properties;
import java.util.Vector;

public class Client extends PMClientBase {

    private static final XAddress aRef[] = new XAddress[5];
    private static final XAnnualReview rRef[] = new XAnnualReview[10];
    private static final XCompany cRef[] = new XCompany[5];
    private static final XInsurance insRef[] = new XInsurance[5];
    private static final XPerson pRef[] = new XPerson[20];
    private static final XProject projRef[] = new XProject[10];
    private static final XTeam tRef[] = new XTeam[10];

    public Client() {
    }

    public static void main(String[] args) {
        Client theTests = new Client();
        Status s = theTests.run(args, System.out, System.err);
        s.exit();
    }

    public void setup(String[] args, Properties p) throws Fault {
        TestUtil.logTrace("setup");
        try {

            super.setup(args, p);
            removeTestData();

        } catch (Exception e) {
            TestUtil.logErr("Exception: " , e);
            throw new Fault("Setup failed:", e);
        }
    }


    /*
     * @testName: descriptorMappingTest1
     * @assertion_ids: PERSISTENCE:SPEC:1144; PERSISTENCE:SPEC:919;
     *                 PERSISTENCE:SPEC:949;
     *                 PERSISTENCE:SPEC:950
     * @test_Strategy: RelationShip Mapping Using Descriptors
     *			BiDirectional OneToOne Relationship
     *
     *			OnePerson to OneProjectLead
     *
     *			Entity Person mapped to table named PERSON references
     *				a single instance of Project.
     *			Entity Project mapped to table named PROJECT
     *				a single instance of Person.
     *			Entity Person is the owner of the relationship.
     *
     *			Table PERSON contains a foreign key to PROJECT.
     *			The foreign key is named PROJECT_PROJID.
     *               
     */

    public void descriptorMappingTest1() throws Fault {

        TestUtil.logTrace("Begin descriptorMappingTest1");
        boolean pass = false;

        try {
            createPeople();
            createProjects();
            getEntityTransaction().begin();

            pRef[0].setXProject(projRef[2]);
            projRef[2].setXProjectLead(pRef[0]);

            getEntityManager().merge(pRef[0]);
            getEntityManager().merge(projRef[2]);

            XPerson newPerson = getEntityManager().find(XPerson.class, 1);

            if (newPerson.getXProject().getXName().equals("Asp")) {
                TestUtil.logTrace("Expected results received");
                pass = true;
            }

            getEntityTransaction().commit();

        } catch (Exception e) {
            TestUtil.logErr("Unexpected exception occurred", e);
        } finally {
            try {
                if (getEntityTransaction().isActive()) {
                    getEntityTransaction().rollback();
                }
            } catch (Exception re) {
                TestUtil.logErr("Unexpected Exception in rollback:",re);
            }
        }

        if (!pass)
            throw new Fault("descriptorMappingTest1 failed");
    }


    /*
     * @testName: descriptorMappingTest2
     * @assertion_ids: PERSISTENCE:SPEC:1144; PERSISTENCE:SPEC:919;

     * @test_Strategy: RelationShip Mapping Using Descriptors
     *			BiDirectional ManyToOne Relationship
     *
     *			ManyTeams to OneCompany
     *
     *			Entity Team is mapped to a table named TEAM references
     *				a single instance of Company.
     *			Entity Company mapped to table named COMPANY references
     *				a collection of Entity Team.
     *			Entity Team is the owner of the relationship.
     *
     *			Table TEAM contains a foreign key to COMPANY.
     *			The foreign key is named COMPANY_COMPANYID.
     *               
     */

    public void descriptorMappingTest2() throws Fault {

        TestUtil.logTrace("Begin descriptorMappingTest2");
        boolean pass1 = true;
        boolean pass2 = false;
        Vector<XTeam> v1;
        Vector<XTeam> v2;
        int foundTeam1 = 0;
        int foundTeam2 = 0;
        final String[] expectedTeam1 = new String[]{"Engineering", "Marketing", "Sales"};
        final String[] expectedTeam2 = new String[]{"Accounting", "Training"};


        try {
            createTeams();
            createCompany();

            getEntityTransaction().begin();

            tRef[0].setXCompany(cRef[0]);
            tRef[1].setXCompany(cRef[0]);
            tRef[2].setXCompany(cRef[0]);

            v1 = new Vector<XTeam>();
            v1.add(tRef[0]);
            v1.add(tRef[1]);
            v1.add(tRef[2]);
            cRef[0].setXTeams(v1);

            tRef[3].setXCompany(cRef[1]);
            tRef[4].setXCompany(cRef[1]);

            v2 = new Vector<XTeam>();
            v2.add(tRef[3]);
            v2.add(tRef[4]);
            cRef[1].setXTeams(v2);

            getEntityManager().merge(tRef[0]);
            getEntityManager().merge(tRef[1]);
            getEntityManager().merge(tRef[2]);
            getEntityManager().merge(tRef[3]);
            getEntityManager().merge(tRef[4]);

            getEntityManager().merge(cRef[0]);
            getEntityManager().merge(cRef[1]);
            getEntityManager().flush();

            XCompany c1 = getEntityManager().find(XCompany.class, 25501L);
            Collection<XTeam> t1 = c1.getXTeams();

            XCompany c2 = getEntityManager().find(XCompany.class, 37560L);
            Collection<XTeam> t2 = c2.getXTeams();


            if ((t1.size() != 3) || (t2.size() != 2)) {
                TestUtil.logErr("descriptorMappingTest2: Did not get expected results."
                        + "Team1 Collection Expected 3 references, got: "
                        + t1.size()
                        + ", Team2 Collection Expected 2 references, got: "
                        + t2.size());
                pass1 = false;
            } else if (pass1) {

                Iterator i1 = t1.iterator();
                while (i1.hasNext()) {
                    TestUtil.logTrace("Check Team 1 Collection for expected Teams");
                    XTeam o1 = (XTeam) i1.next();

                    for (int l = 0; l < 3; l++) {
                        if (expectedTeam1[l].equals( o1.getXName())) {
                            TestUtil.logTrace("Found Team 1:" +  o1.getXName());
                            foundTeam1++;
                            break;
                        }
                    }
                }

                Iterator i2 = t2.iterator();
                while (i2.hasNext()) {
                    TestUtil.logTrace("Check Team 2 Collection for expected Teams");
                    XTeam o2 = (XTeam) i2.next();

                    for (int l = 0; l < 2; l++) {
                        if (expectedTeam2[l].equals( o2.getXName())) {
                            TestUtil.logTrace("Found Team 2:" +  o2.getXName());
                            foundTeam2++;
                            break;
                        }
                    }
                }
            }


            if ((foundTeam1 != 3) || (foundTeam2 != 2)) {
                TestUtil.logErr("descriptorMappingTest2: Did not get expected results");
                pass2 = false;
            } else {
                TestUtil.logTrace("Expected results received");
                pass2 = true;
            }


            getEntityTransaction().commit();

        } catch (Exception e) {
            TestUtil.logErr("Unexpected exception occurred", e);
        } finally {
            try {
                if (getEntityTransaction().isActive()) {
                    getEntityTransaction().rollback();
                }
            } catch (Exception re) {
                TestUtil.logErr("Unexpected Exception in rollback:",re);
            }

        }

        if (!pass2)
            throw new Fault("descriptorMappingTest2 failed");
    }


    /*
     * @testName: descriptorMappingTest3
     * @assertion_ids: PERSISTENCE:SPEC:1144; PERSISTENCE:SPEC:919;

     * @test_Strategy: RelationShip Mapping Using Descriptors
     *			BiDirectional OneToMany Relationship
     *
     *                  OneCompany To ManyTeams
     *
     *                  Entity Company mapped to table named COMPANY references
     *                          a collection of Entity Team.
     *                  Entity Team is mapped to a table named TEAM references
     *                          a single instance of Entity Company.
     *                  Entity Team is the owner of the relationship.
     *
     *                  Table TEAM contains a foreign key to COMPANY.
     *                  The foreign key is named COMPANY_COMPANYID.
     *
     */

    public void descriptorMappingTest3() throws Fault {

        TestUtil.logTrace("Begin descriptorMappingTest3");
        boolean pass = false;
        Vector v1;
        Vector v2;

        try {
            createTeams();
            createCompany();

            getEntityTransaction().begin();

            tRef[0].setXCompany(cRef[0]);
            tRef[1].setXCompany(cRef[0]);

            v1 = new Vector();
            v1.add(tRef[0]);
            v1.add(tRef[1]);
            cRef[0].setXTeams(v1);

            tRef[2].setXCompany(cRef[1]);
            tRef[3].setXCompany(cRef[1]);
            tRef[4].setXCompany(cRef[1]);

            v2 = new Vector();
            v2.add(tRef[2]);
            v2.add(tRef[3]);
            v2.add(tRef[4]);

            cRef[1].setXTeams(v2);

            getEntityManager().merge(tRef[0]);
            getEntityManager().merge(tRef[1]);
            getEntityManager().merge(tRef[2]);
            getEntityManager().merge(tRef[3]);
            getEntityManager().merge(tRef[4]);

            getEntityManager().merge(cRef[0]);
            getEntityManager().merge(cRef[1]);

            getEntityManager().flush();

            XTeam t1 = getEntityManager().find(XTeam.class, 1);
            XTeam t2 = getEntityManager().find(XTeam.class, 2);
            XTeam t3 = getEntityManager().find(XTeam.class, 3);
            XTeam t4 = getEntityManager().find(XTeam.class, 4);
            XTeam t5 = getEntityManager().find(XTeam.class, 5);


            if ((t1.getXCompany().getXCompanyId() == 25501L) &&
                    (t2.getXCompany().getXCompanyId() == 25501L) &&
                    (t3.getXCompany().getXCompanyId() == 37560L) &&
                    (t4.getXCompany().getXCompanyId() == 37560L) &&
                    (t5.getXCompany().getXCompanyId() == 37560L)) {

                pass = true;
            }

            getEntityTransaction().commit();

        } catch (Exception e) {
            TestUtil.logErr("Unexpected exception occurred", e);
        } finally {
            try {
                if (getEntityTransaction().isActive()) {
                    getEntityTransaction().rollback();
                }
            } catch (Exception re) {
                TestUtil.logErr("Unexpected Exception in rollback:",re);
            }
        }

        if (!pass)
            throw new Fault("descriptorMappingTest3 failed");
    }


    /*
     * @testName: descriptorMappingTest4
     * @assertion_ids: PERSISTENCE:SPEC:1144; PERSISTENCE:SPEC:919;

     * @test_Strategy: RelationShip Mapping Using Descriptors
     *                  UniDirectional OneToOne Relationship
     *
     *                  OneCompany To OneAddress
     *
     *                  Entity Company mapped to table named COMPANY references
     *                          a single instance of Entity Address.
     *                  Entity Address is mapped to a table named ADDRESS which
     *                          does not reference Entity Company.
     *                  Entity Company is the owner of the relationship.
     *
     *                  Table COMPANY contains a foreign key to ADDRESS.
     *                  The foreign key is named ADDRESS_ID.
     *
     */

    public void descriptorMappingTest4() throws Fault {

        TestUtil.logTrace("Begin descriptorMappingTest4");
        boolean pass = false;


        try {

            createAddress();
            createCompany();

            getEntityTransaction().begin();

            cRef[0].setXAddress(aRef[0]);
            cRef[1].setXAddress(aRef[1]);

            getEntityManager().merge(cRef[0]);
            getEntityManager().merge(cRef[1]);

            getEntityManager().flush();

            XCompany c1 = getEntityManager().find(XCompany.class, 25501L);
            XCompany c2 = getEntityManager().find(XCompany.class, 37560L);

            if (c1.getXAddress().getXCity().equals("Burlington") &&
                    c2.getXAddress().getXCity().equals("Santa Clara")) {
                TestUtil.logTrace("Expected results received");
                pass = true;
            } else {
                TestUtil.logErr("Did not get expected results" +
                        "Expected: Burlington and Santa Clara, got: " +
                        c1.getXAddress().getXCity() + c2.getXAddress().getXCity());
            }

            getEntityTransaction().commit();

        } catch (Exception e) {
            TestUtil.logErr("Unexpected exception occurred", e);
        } finally {
            try {
                if (getEntityTransaction().isActive()) {
                    getEntityTransaction().rollback();
                }
            } catch (Exception re) {
                TestUtil.logErr("Unexpected Exception in rollback:",re);
            }

        }


        if (!pass)
            throw new Fault("descriptorMappingTest4 failed");
    }

    /*
     * @testName: descriptorMappingTest5
     * @assertion_ids: PERSISTENCE:SPEC:1144; PERSISTENCE:SPEC:919;

     * @test_Strategy: RelationShip Mapping Using Descriptors
     *                  UniDirectional ManyToOne Relationship
     *
     *                  ManyPersons To OneTeam
     *
     *                  Entity Person mapped to table named PERSON references
     *                          a single instance of Entity Team.
     *                  Entity Team is mapped to a table named TEAM and
     *                          does not reference Entity Person.
     *                  Entity Person is the owner of the relationship.
     *
     *                  Table PERSON contains a foreign key to TEAM.
     *                  The foreign key is named TEAM_TEAMID.
     *
     */

    public void descriptorMappingTest5() throws Fault {
        TestUtil.logTrace("Begin descriptorMappingTest5");
        boolean pass = false;

        try {
            createTeams();
            createPeople();

            getEntityTransaction().begin();

            pRef[1].setXTeam(tRef[0]);
            pRef[3].setXTeam(tRef[1]);
            pRef[5].setXTeam(tRef[2]);
            pRef[7].setXTeam(tRef[3]);
            pRef[9].setXTeam(tRef[4]);

            pRef[2].setXTeam(tRef[4]);
            pRef[4].setXTeam(tRef[3]);
            pRef[6].setXTeam(tRef[2]);
            pRef[8].setXTeam(tRef[1]);
            pRef[10].setXTeam(tRef[0]);


            for (int i = 1; i < 11; i++) {
                getEntityManager().merge(pRef[i]);
            }

            getEntityManager().flush();

            if ((pRef[1].getXTeam() == tRef[0]) && (pRef[10].getXTeam() == tRef[0]) &&
                    (pRef[3].getXTeam() == tRef[1]) && (pRef[8].getXTeam() == tRef[1]) &&
                    (pRef[5].getXTeam() == tRef[2]) && (pRef[6].getXTeam() == tRef[2]) &&
                    (pRef[7].getXTeam() == tRef[3]) && (pRef[4].getXTeam() == tRef[3]) &&
                    (pRef[9].getXTeam() == tRef[4]) && (pRef[2].getXTeam() == tRef[4])) {

                TestUtil.logTrace("Expected results received");
                pass = true;
            } else {
                TestUtil.logErr("Did not get expected results");
                pass = false;
            }


            getEntityTransaction().commit();

        } catch (Exception e) {
            TestUtil.logErr("Unexpected exception occurred", e);
        } finally {
            try {
                if (getEntityTransaction().isActive()) {
                    getEntityTransaction().rollback();
                }
            } catch (Exception re) {
                TestUtil.logErr("Unexpected Exception in rollback:",re);
            }

        }

        if (!pass)
            throw new Fault("descriptorMappingTest5 failed");
    }


    /*
     * @testName: descriptorMappingTest6
     * @assertion_ids: PERSISTENCE:SPEC:1144; PERSISTENCE:SPEC:919;

     * @test_Strategy: RelationShip Mapping Using Descriptors
     *                  BiDirectional ManyToMany Relationship
     *
     *                  ManyProjects To ManyPersons
     *
     *                  Entity Project mapped to table named PROJECT 
     *                          references a collection of Entity Project.
     *                  Entity Person is mapped to a table named PERSON and
     *                          references a collection of Entity Project.
     *                  Entity Project is the owner of the relationship.
     *
     *			There is a join table named PROJECT_PERSON (owner
     *			named first.  One foreign key column refers to table
     *			PROJECT.  The name of the foreign key column is
     *			PROJECTS_PROJID.  The other foreign key column is
     *			refers to the PERSON table.  The name of this foreign
     *			key is PERSONS_PERSONID. 
     *
     */

    public void descriptorMappingTest6() throws Fault {
        TestUtil.logTrace("Begin descriptorMappingTest6");
        boolean pass1 = true;
        boolean pass2 = false;
        int foundProject1 = 0;
        int foundProject2 = 0;
        final Long[] expectedResults1 = new Long[]{123456789L, 345678901L, 567890123L};
        final Long[] expectedResults2 = new Long[]{234567890L, 345678901L, 456789012L};

        try {
            createPeople();
            createProjects();

            getEntityTransaction().begin();


            pRef[5].getXProjects().add(projRef[0]);
            pRef[5].getXProjects().add(projRef[2]);
            pRef[5].getXProjects().add(projRef[4]);
            getEntityManager().merge(pRef[5]);


            pRef[8].getXProjects().add(projRef[1]);
            pRef[8].getXProjects().add(projRef[2]);
            pRef[8].getXProjects().add(projRef[3]);
            getEntityManager().merge(pRef[8]);

            projRef[0].getXPersons().add(pRef[5]);
            getEntityManager().merge(projRef[0]);

            projRef[1].getXPersons().add(pRef[8]);
            getEntityManager().merge(projRef[1]);

            projRef[2].getXPersons().add(pRef[5]);
            getEntityManager().merge(projRef[2]);

            projRef[2].getXPersons().add(pRef[8]);
            getEntityManager().merge(projRef[2]);

            projRef[3].getXPersons().add(pRef[8]);
            getEntityManager().merge(projRef[3]);


            projRef[4].getXPersons().add(pRef[5]);
            getEntityManager().merge(projRef[4]);


            getEntityManager().flush();

            XPerson p1 = getEntityManager().find(XPerson.class, 6);
            XPerson p2 = getEntityManager().find(XPerson.class, 9);

            Collection<XProject> projCol1 = p1.getXProjects();
            Collection<XProject> projCol2 = p2.getXProjects();

            if ((projCol1.size() != 3) || (projCol2.size() != 3)) {
                TestUtil.logErr("descriptorMappingTest6: Did not get expected results."
                        + "Expected 3 Projects for Karen Tegan (PK 6) , got: "
                        + projCol1.size()
                        + ", Expected 2 Projects for William Keaton (PK 9), got: "
                        + projCol2.size());
                pass1 = false;
            } else if (pass1) {

                Iterator i1 = projCol1.iterator();
                while (i1.hasNext()) {
                    TestUtil.logTrace("Check Collection for Karen Tegan Projects");
                    XProject o1 = (XProject) i1.next();

                    for (int l = 0; l < 3; l++) {
                        if (expectedResults1[l].equals(o1.getXProjId())) {
                            TestUtil.logTrace("Found Project for Karen Tegan: "
                                    + o1.getXName());
                            foundProject1++;
                            break;
                        }
                    }
                }


                Iterator i2 = projCol2.iterator();
                while (i2.hasNext()) {
                    TestUtil.logTrace("Check Collection for William Keaton Projects");
                    XProject o2 = (XProject) i2.next();

                    for (int l = 0; l < 3; l++) {
                        if (expectedResults2[l].equals(o2.getXProjId())) {
                            TestUtil.logTrace("Found Project for William Keaton: "
                                    + o2.getXName());
                            foundProject2++;
                            break;
                        }
                    }
                }

            }

            if ((foundProject1 != 3) || (foundProject2 != 3)) {
                TestUtil.logErr("descriptorMappingTest6: Did not get expected results");
                pass2 = false;
            } else {
                TestUtil.logTrace("Expected results received");
                pass2 = true;
            }

            Collection<XPerson> nullPersonCol = new Vector<XPerson>();
            projRef[0].setXPersons(nullPersonCol);
            getEntityManager().merge(projRef[0]);

            projRef[1].setXPersons(nullPersonCol);
            getEntityManager().merge(projRef[1]);

            projRef[2].setXPersons(nullPersonCol);
            getEntityManager().merge(projRef[2]);

            projRef[3].setXPersons(nullPersonCol);
            getEntityManager().merge(projRef[3]);

            projRef[4].setXPersons(nullPersonCol);
            getEntityManager().merge(projRef[4]);

            getEntityTransaction().commit();

        } catch (Exception e) {
            TestUtil.logErr("Unexpected exception occurred", e);
        } finally {
            try {
                if (getEntityTransaction().isActive()) {
                    getEntityTransaction().rollback();
                }
            } catch (Exception re) {
                TestUtil.logErr("Unexpected Exception in rollback:",re);
            }
        }


        if (!pass1 || !pass2)
            throw new Fault("descriptorMappingTest6 failed");
    }


    /*
     * @testName: descriptorMappingTest7
     * @assertion_ids: PERSISTENCE:SPEC:1144; PERSISTENCE:SPEC:919;

     * @test_Strategy: RelationShip Mapping Using Descriptors
     *                 UniDirectional OneToMany Relationship
     *
     *                  OnePerson To ManyReviews
     *
     *                  Entity Person mapped to table named PERSON
     *                          references a collection of Entity AnnualReview.
     *                  Entity AnnualReview is mapped to a table named
     *				ANNUALREVIEW which does not reference Entity Person.
     *                  Entity Person is the owner of the relationship.
     *
     *                  There is a join table named PERSON_ANNUALREVIEW (owner
     *                  named first.  One foreign key column refers to table
     *                  PERSON.  The name of the foreign key column is
     *                  PERSON_PERSONID.  The other foreign key column is
     *                  refers to the ANNUALREVIEW table.  The name of this foreign
     *                  key is ANNUALREVIEWS_AID.
     *
     */

    public void descriptorMappingTest7() throws Fault {
        TestUtil.logTrace("Begin descriptorMappingTest7");
        boolean pass1 = true;
        boolean pass2 = false;

        Vector<XAnnualReview> v1 = null;
        Vector<XAnnualReview> v2 = null;
        Vector<XAnnualReview> v3 = null;
        Vector<XAnnualReview> v4 = null;
        int foundCol1 = 0;
        int foundCol2 = 0;
        int foundCol3 = 0;
        int foundCol4 = 0;
        int foundCol5 = 0;
        Integer[] expectedCol1 = new Integer[]{1,2,3,4};
        Integer[] expectedCol2 = new Integer[]{5,6};
        Integer[] expectedCol3 = new Integer[]{3,8};
        Integer[] expectedCol4 = new Integer[]{4,7};
        Integer[] expectedCol5 = new Integer[]{1,2,3,4};

        try {
            createReviews();
            createPeople();

            getEntityTransaction().begin();

            v1 = new Vector<XAnnualReview>();
            v1.add(rRef[0]);
            v1.add(rRef[1]);
            v1.add(rRef[2]);
            v1.add(rRef[3]);

            v2 = new Vector<XAnnualReview>();
            v2.add(rRef[4]);
            v2.add(rRef[5]);

            v3 = new Vector<XAnnualReview>();
            v3.add(rRef[2]);
            v3.add(rRef[7]);

            v4 = new Vector<XAnnualReview>();
            v4.add(rRef[3]);
            v4.add(rRef[6]);


            pRef[11].setXAnnualReviews(v1);
            pRef[13].setXAnnualReviews(v2);
            pRef[15].setXAnnualReviews(v3);
            pRef[17].setXAnnualReviews(v4);
            pRef[19].setXAnnualReviews(v1);


            getEntityManager().merge(pRef[11]);
            getEntityManager().merge(pRef[13]);
            getEntityManager().merge(pRef[15]);
            getEntityManager().merge(pRef[17]);
            getEntityManager().merge(pRef[19]);

            getEntityManager().flush();

            XPerson p1 = getEntityManager().find(XPerson.class, 12);
            XPerson p2 = getEntityManager().find(XPerson.class, 14);
            XPerson p3 = getEntityManager().find(XPerson.class, 16);
            XPerson p4 = getEntityManager().find(XPerson.class, 18);
            XPerson p5 = getEntityManager().find(XPerson.class, 20);


            Collection<XAnnualReview> col1 = p1.getXAnnualReviews();
            Collection<XAnnualReview> col2 = p2.getXAnnualReviews();
            Collection<XAnnualReview> col3 = p3.getXAnnualReviews();
            Collection<XAnnualReview> col4 = p4.getXAnnualReviews();
            Collection<XAnnualReview> col5 = p5.getXAnnualReviews();

            if ((col1.size() != 4) || (col2.size() != 2 ||
                    col3.size() != 2 || col4.size() != 2 || col5.size() != 4)) {
                TestUtil.logErr("descriptorMappingTest7: Did not get expected results."
                        + "Expected 4 reviews for Mary Macy (PK 12) , got: "
                        + col1.size()
                        + ", Expected 2 reviews for Julie OClaire (PK 14), got: "
                        + col2.size()
                        + ", Expected 2 reviews for Kellie Lee (PK 16), got: "
                        + col3.size()
                        + ", Expected 2 reviews for Mark Francis (PK 18), got: "
                        + col4.size()
                        + ", Expected 4 reviews for Katy Hughes (PK 20), got: "
                        + col5.size());
                pass1 = false;
            } else if (pass1) {

                Iterator i1 = col1.iterator();
                while (i1.hasNext()) {
                    TestUtil.logTrace("Check Collection for Mary Macy Reviews");
                    XAnnualReview o1 = (XAnnualReview) i1.next();

                    for (int l = 0; l < 5; l++) {
                        if (expectedCol1[l].equals(o1.getXService())) {
                            TestUtil.logTrace("Found Mary Macy Annual Review for Service Year: "
                                    +  o1.getXService());
                            foundCol1++;
                            break;
                        }
                    }
                }


                Iterator i2 = col2.iterator();
                while (i2.hasNext()) {
                    TestUtil.logTrace("Check Collection for Julie OClaire Reviews");
                    XAnnualReview o2 = (XAnnualReview) i2.next();

                    for (int l = 0; l < 2; l++) {
                        if (expectedCol2[l].equals( o2.getXService())) {
                            TestUtil.logTrace("Found Julie OClaire Annual Review for Service Year: "
                                    +  o2.getXService());
                            foundCol2++;
                            break;
                        }
                    }
                }

                Iterator i3 = col3.iterator();
                while (i3.hasNext()) {
                    TestUtil.logTrace("Check Collection for Kellie Lee Reviews");
                    XAnnualReview o3 = (XAnnualReview) i3.next();

                    for (int l = 0; l < 2; l++) {
                        if (expectedCol3[l].equals( o3.getXService())) {
                            TestUtil.logTrace("Found Kellie Lee Annual Review for Service Year: "
                                    +  o3.getXService());
                            foundCol3++;
                            break;
                        }
                    }
                }


                Iterator i4 = col4.iterator();
                while (i4.hasNext()) {
                    TestUtil.logTrace("Check Collection for Mark Francis Reviews");
                    XAnnualReview o4 = (XAnnualReview) i4.next();

                    for (int l = 0; l < 2; l++) {
                        if (expectedCol4[l].equals( o4.getXService())) {
                            TestUtil.logTrace("Found Mark Francis Annual Review for Service Year: "
                                    +  o4.getXService());
                            foundCol4++;
                            break;
                        }
                    }
                }


                Iterator i5 = col5.iterator();
                while (i5.hasNext()) {
                    TestUtil.logTrace("Check Collection for Katy Hughes Reviews");
                    XAnnualReview o5 = (XAnnualReview) i5.next();

                    for (int l = 0; l < 5; l++) {
                        if (expectedCol5[l].equals( o5.getXService())) {
                            TestUtil.logTrace("Found Katy Hughes Annual Review for Service Year: "
                                    +  o5.getXService());
                            foundCol5++;
                            break;
                        }
                    }
                }

            }

            if ((foundCol1 != 4) || (foundCol2 != 2) ||
                    (foundCol3 != 2) || (foundCol4 != 2) || (foundCol5 != 4)) {

                TestUtil.logErr("descriptorMappingTest7: Did not get expected results");
                pass2 = false;
            } else {
                TestUtil.logTrace("Expected results received");
                pass2 = true;
            }


            getEntityTransaction().commit();

        } catch (Exception e) {
            TestUtil.logErr("Unexpected exception occurred", e);
        } finally {
            try {
                if (getEntityTransaction().isActive()) {
                    getEntityTransaction().rollback();
                }
            } catch (Exception re) {
                TestUtil.logErr("Unexpected Exception in rollback:",re);
            }
        }

        if (!pass1 || !pass2)
            throw new Fault("descriptorMappingTest7 failed");
    }


    /*
    * @testName: descriptorMappingTest8
    * @assertion_ids: PERSISTENCE:SPEC:1144; PERSISTENCE:SPEC:919;
    * @test_Strategy: RelationShip Mapping Using Descriptors
    *                  UniDirectional ManyToMany Relationship
    *
    *                  ManyPersons To ManyInsurances
    *
    *                  Entity Person mapped to table named PERSON
    *                          references a collection of Entity Insurance.
    *                  Entity Insurance is mapped to a table named INSURANCE and
    *                          which does not reference Entity Person.
    *                  Entity Person is the owner of the relationship.
    *
    *                  There is a join table named PERSON_INSURANCE (owner
    *                  named first.  One foreign key column refers to table
    *                  PERSON.  The name of the foreign key column is
    *                  PERSON_PERSONID.  The other foreign key column is
    *                  refers to the INSURANCE table.  The name of this foreign
    *                  key is INSURANCES_INSID.
    *
    */

    public void descriptorMappingTest8() throws Fault {
        boolean pass1 = true;
        boolean pass2 = false;
        int foundInsurance1 = 0;
        int foundInsurance2 = 0;
        int foundInsurance3 = 0;
        Integer[] expectedResults1 = new Integer[]{1,3};
        Integer[] expectedResults2 = new Integer[]{2,3};
        Integer[] expectedResults3 = new Integer[]{1,2,3};

        try {
            createPeople();
            createInsurance();

            getEntityTransaction().begin();


            pRef[2].getXInsurance().add(insRef[0]);
            pRef[2].getXInsurance().add(insRef[2]);
            getEntityManager().merge(pRef[2]);

            pRef[12].getXInsurance().add(insRef[1]);
            pRef[12].getXInsurance().add(insRef[2]);
            getEntityManager().merge(pRef[12]);

            pRef[16].getXInsurance().add(insRef[0]);
            pRef[16].getXInsurance().add(insRef[1]);
            pRef[16].getXInsurance().add(insRef[2]);
            getEntityManager().merge(pRef[16]);


            getEntityManager().flush();

            XPerson p1 = getEntityManager().find(XPerson.class, 3);
            XPerson p2 = getEntityManager().find(XPerson.class, 13);
            XPerson p3 = getEntityManager().find(XPerson.class, 17);

            Collection<XInsurance> insCol1 = p1.getXInsurance();
            Collection<XInsurance> insCol2 = p2.getXInsurance();
            Collection<XInsurance> insCol3 = p3.getXInsurance();

            if ((insCol1.size() != 2) || (insCol2.size() != 2) || (insCol3.size() != 3)) {
                TestUtil.logErr("descriptorMappingTest8: Did not get expected results."
                        + "Expected 2 Insurance Carriers for Shelly McGowan (PK 3) , got: "
                        + insCol1.size()
                        + ", Expected 2 Insurance Carriers for Cheng Fang (PK 13) , got: "
                        + insCol2.size()
                        + ", Expected 3 Insurance Carriers for Nicole Martin (PK 17), got: "
                        + insCol3.size());
                pass1 = false;
            } else if (pass1) {

                Iterator i1 = insCol1.iterator();
                while (i1.hasNext()) {
                    TestUtil.logTrace("Check Insurance Carriers for Shelly McGowan");
                    XInsurance o1 = (XInsurance) i1.next();

                    for (int l = 0; l < 2; l++) {
                        if (expectedResults1[l].equals( o1.getXInsId())) {
                            TestUtil.logTrace("Found Insurance Carrier for Shelly McGowan: "
                                    +  o1.getXCarrier());
                            foundInsurance1++;
                            break;
                        }
                    }
                }

                Iterator i2 = insCol2.iterator();
                while (i2.hasNext()) {
                    TestUtil.logTrace("Check Insurance Carriers for Cheng Fang");
                    XInsurance o2 = (XInsurance) i2.next();

                    for (int l = 0; l < 2; l++) {
                        if (expectedResults2[l].equals( o2.getXInsId())) {
                            TestUtil.logTrace("Found Insurance Carrier for Cheng Fang: "
                                    +  o2.getXCarrier());
                            foundInsurance2++;
                            break;
                        }
                    }
                }

                Iterator i3 = insCol3.iterator();
                while (i3.hasNext()) {
                    TestUtil.logTrace("Check Insurance Carriers for Nicole Martin");
                    XInsurance o3 = (XInsurance) i3.next();

                    for (int l = 0; l < 3; l++) {
                        if (expectedResults3[l].equals( o3.getXInsId())) {
                            TestUtil.logTrace("Found Insurance Carrier for Nicole Martin: "
                                    +  o3.getXCarrier());
                            foundInsurance3++;
                            break;
                        }
                    }
                }

            }

            if ((foundInsurance1 != 2) || (foundInsurance2 != 2) || (foundInsurance3 != 3)) {
                TestUtil.logErr("descriptorMappingTest8: Did not get expected results");
                pass2 = false;
            } else {
                TestUtil.logTrace("Expected results received");
                pass2 = true;
            }

            getEntityTransaction().commit();

        } catch (Exception e) {
            TestUtil.logErr("Unexpected exception occurred", e);
        } finally {
            try {
                if (getEntityTransaction().isActive()) {
                    getEntityTransaction().rollback();
                }
            } catch (Exception re) {
                TestUtil.logErr("Unexpected Exception in rollback:",re);
            }
        }

        if (!pass1 || !pass2)
            throw new Fault("descriptorMappingTest8 failed");
    }

    /*
    *  Business Methods to set up data for Test Cases
    */

    private void createPeople() throws Exception {
        TestUtil.logTrace("CreatePeople");

        TestUtil.logTrace("Create 20 People");
        pRef[0] = new XPerson(1, "Alan", "Frechette");
        pRef[1] = new XPerson(2, "Arthur", "Frechette");
        pRef[2] = new XPerson(3, "Shelly", "McGowan");
        pRef[3] = new XPerson(4, "Robert", "Bissett");
        pRef[4] = new XPerson(5, "Stephen", "DMilla");
        pRef[5] = new XPerson(6, "Karen", "Tegan");
        pRef[6] = new XPerson(7, "Stephen", "Cruise");
        pRef[7] = new XPerson(8, "Irene", "Caruso");
        pRef[8] = new XPerson(9, "William", "Keaton");
        pRef[9] = new XPerson(10, "Kate", "Hudson");
        pRef[10] = new XPerson(11, "Jonathan", "Smith");
        pRef[11] = new XPerson(12, "Mary", "Macy");
        pRef[12] = new XPerson(13, "Cheng", "Fang");
        pRef[13] = new XPerson(14, "Julie", "OClaire");
        pRef[14] = new XPerson(15, "Steven", "Rich");
        pRef[15] = new XPerson(16, "Kellie", "Lee");
        pRef[16] = new XPerson(17, "Nicole", "Martin");
        pRef[17] = new XPerson(18, "Mark", "Francis");
        pRef[18] = new XPerson(19, "Will", "Forrest");
        pRef[19] = new XPerson(20, "Katy", "Hughes");

        TestUtil.logTrace("Start to persist people ");
        getEntityTransaction().begin();
        for (XPerson p : pRef) {
            getEntityManager().persist(p);
            TestUtil.logTrace("persisted person " + p);
        }
        getEntityTransaction().commit();
    }

    private void createTeams() throws Exception {

        TestUtil.logTrace("Create 5 Teams");
        tRef[0] = new XTeam(1, "Engineering");
        tRef[1] = new XTeam(2, "Marketing");
        tRef[2] = new XTeam(3, "Sales");
        tRef[3] = new XTeam(4, "Accounting");
        tRef[4] = new XTeam(5, "Training");

        TestUtil.logTrace("Start to persist teams ");
        getEntityTransaction().begin();
        for (XTeam t : tRef) {
            if (t != null) {
                getEntityManager().persist(t);
                TestUtil.logTrace("persisted team " + t);
            }
        }
        getEntityTransaction().commit();

    }

    private void createInsurance() throws Exception {
        TestUtil.logTrace("Create 3 Insurance Carriers");
        insRef[0] = new XInsurance(1, "Prudential");
        insRef[1] = new XInsurance(2, "Cigna");
        insRef[2] = new XInsurance(3, "Sentry");

        TestUtil.logTrace("Start to persist insurance ");
        getEntityTransaction().begin();
        for (XInsurance i : insRef) {
            if (i != null) {

                getEntityManager().persist(i);
                TestUtil.logTrace("persisted insurance " + i);
            }
        }
        getEntityTransaction().commit();

    }

    private void createProjects() throws Exception {
        TestUtil.logTrace("Create 5 Projects");
        projRef[0] = new XProject(123456789L, "Sidewinder", new BigDecimal("20500.0"));
        projRef[1] = new XProject(234567890L, "Boa", new BigDecimal("75000.0"));
        projRef[2] = new XProject(345678901L, "Asp", new BigDecimal("500000.0"));
        projRef[3] = new XProject(456789012L, "King Cobra", new BigDecimal("250000.0"));
        projRef[4] = new XProject(567890123L, "Python", new BigDecimal("1000.0"));

        TestUtil.logTrace("Start to persist projects ");
        getEntityTransaction().begin();
        for (XProject p : projRef) {
            if (p != null) {

                getEntityManager().persist(p);
                TestUtil.logTrace("persisted project " + p);
            }
        }
        getEntityTransaction().commit();

    }

    private void createCompany() throws Exception {

        TestUtil.logTrace("Create 2 Companies");
        cRef[0] = new XCompany(25501L, "American Gifts");
        cRef[1] = new XCompany(37560L, "Planet Earth");

        TestUtil.logTrace("Start to persist companies ");
        getEntityTransaction().begin();

        for (XCompany c : cRef) {
            if (c != null) {

                getEntityManager().persist(c);
                TestUtil.logTrace("persisted company " + c);
            }
        }
        getEntityTransaction().commit();

    }

    private void createAddress() throws Exception {
        TestUtil.logTrace("Create 2 Addresses");
        aRef[0] = new XAddress("100", "1 Network Drive", "Burlington", "MA", "01803");
        aRef[1] = new XAddress("200", "4150 Network Drive", "Santa Clara", "CA", "95054");

        TestUtil.logTrace("Start to persist addresses ");
        getEntityTransaction().begin();
        for (XAddress a : aRef) {
            if (a != null) {
                getEntityManager().persist(a);
                TestUtil.logTrace("persisted address " + a);
            }
        }
        getEntityTransaction().commit();


    }

    private void createReviews() throws Exception {
        TestUtil.logTrace("Create 5 Addresses");
        rRef[0] = new XAnnualReview(1, 1);
        rRef[1] = new XAnnualReview(2, 2);
        rRef[2] = new XAnnualReview(3, 3);
        rRef[3] = new XAnnualReview(4, 4);
        rRef[4] = new XAnnualReview(5, 5);
        rRef[5] = new XAnnualReview(6, 6);
        rRef[6] = new XAnnualReview(7, 7);
        rRef[7] = new XAnnualReview(8, 8);

        TestUtil.logTrace("Start to persist annual reviews ");
        getEntityTransaction().begin();
        for (XAnnualReview a : rRef) {
            if (a != null) {
                getEntityManager().persist(a);
                TestUtil.logTrace("persisted annual reviews " + a);
            }
        }
        getEntityTransaction().commit();


    }

    public void cleanup() throws Fault {
        TestUtil.logTrace("cleanup");
        removeTestData();
        TestUtil.logTrace("cleanup complete, calling super.cleanup");
        super.cleanup();
    }

    private void removeTestData() {
        TestUtil.logTrace("removeTestData");
        if (getEntityTransaction().isActive()) {
            getEntityTransaction().rollback();
        }
        try {
            getEntityTransaction().begin();
            getEntityManager().createNativeQuery("DELETE FROM PERSON_INSURANCE").executeUpdate();
            getEntityManager().createNativeQuery("DELETE FROM PERSON_ANNUALREVIEW").executeUpdate();
            getEntityManager().createNativeQuery("DELETE FROM INSURANCE").executeUpdate();
            getEntityManager().createNativeQuery("DELETE FROM ANNUALREVIEW").executeUpdate();
            getEntityManager().createNativeQuery("DELETE FROM PERSON").executeUpdate();
            getEntityManager().createNativeQuery("DELETE FROM TEAM").executeUpdate();
            getEntityManager().createNativeQuery("DELETE FROM COMPANY").executeUpdate();
            getEntityManager().createNativeQuery("DELETE FROM ADDRESS").executeUpdate();
            getEntityManager().createNativeQuery("DELETE FROM PROJECT_PERSON").executeUpdate();
            getEntityManager().createNativeQuery("DELETE FROM PROJECT").executeUpdate();
            getEntityTransaction().commit();
        } catch (Exception e) {
            TestUtil.logErr("Exception encountered while removing entities:",e);
        } finally {
            try {
                if (getEntityTransaction().isActive()) {
                    getEntityTransaction().rollback();
                }
            } catch (Exception re) {
                TestUtil.logErr("Unexpected Exception in removeTestData:",re);
            }
        }
    }

}

