/*
 * Copyright 2005 The Apache Software Foundation.
 * 
 * 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 org.apache.jdo.tck.query.operators;

import java.util.Collection;
import java.util.HashSet;

import javax.jdo.JDOUserException;
import javax.jdo.PersistenceManager;
import javax.jdo.Query;
import javax.jdo.Transaction;

import org.apache.jdo.tck.query.QueryTest;
import org.apache.jdo.tck.pc.mylib.PrimitiveTypes;
import org.apache.jdo.tck.util.BatchTestRunner;

/**
 *<B>Title:</B> Boolean Logical AND Query Operator
 *<BR>
 *<B>Keywords:</B> query
 *<BR>
 *<B>Assertion ID:</B> A14.6.2-20.
 *<BR>
 *<B>Assertion Description: </B>
The Boolean logical AND (not bitwise) operator (<code>&amp;</code>) is supported
for all types as they are defined in the Java language.
This includes the following types:
<UL>
<LI><code>Boolean, boolean</code></LI>
</UL>
 */

public class BooleanLogicalAND extends QueryTest {

    /** */
    private static final String ASSERTION_FAILED = 
        "Assertion A14.6.2-20 (BooleanLogicalAND) failed: ";
    
    /**
     * The <code>main</code> is called when the class
     * is directly executed from the command line.
     * @param args The arguments passed to the program.
     */
    public static void main(String[] args) {
        BatchTestRunner.run(BooleanLogicalAND.class);
    }
    
    /** */
    public void test() {
        pm = getPM();
        
        try {
            loadPrimitiveTypes(pm);
            runPositiveTest(pm);
        }
        finally {
            cleanupDatabase(pm, PrimitiveTypes.class);
            pm.close();
            pm = null;
        }
    }

    /** */
    public void testBitwiseAND() {
        pm = getPM();
        
        runNegativeTest(pm);
        
        pm.close();
        pm = null;
    }
    
    /** */
    void runPositiveTest(PersistenceManager pm) {
        if (debug) logger.debug("\nExecuting positive test BooleanLogicalAND() ...");

        Transaction tx = pm.currentTransaction();
        tx.begin();

        Collection instance9 = (Collection)pm.newQuery(
            PrimitiveTypes.class, "id == 9").execute();
        Collection allOddInstances = (Collection)pm.newQuery(
            PrimitiveTypes.class, "booleanNull").execute();
        Collection allInstances = (Collection)pm.newQuery(
            PrimitiveTypes.class, "true").execute();
        Collection empty = new HashSet();
        
        // case true & true
        runSimplePrimitiveTypesQuery("true & true", 
                                     pm, allInstances, ASSERTION_FAILED);

        // case true & false
        runSimplePrimitiveTypesQuery("true & false", 
                                     pm, empty, ASSERTION_FAILED);

        // case false & true
        runSimplePrimitiveTypesQuery("false & true", 
                                     pm, empty, ASSERTION_FAILED);

        // case false & false
        runSimplePrimitiveTypesQuery("false & false", 
                                     pm, empty, ASSERTION_FAILED);

        // case boolean & boolean
        runSimplePrimitiveTypesQuery("intNotNull == 9 & booleanNotNull", 
                                     pm, instance9, ASSERTION_FAILED);

        // case boolean & Boolean
        runSimplePrimitiveTypesQuery("intNotNull == 9 & booleanNull", 
                                     pm, instance9, ASSERTION_FAILED);
        // case Boolean & boolean
        runSimplePrimitiveTypesQuery("booleanNull & intNotNull == 9", 
                                     pm, instance9, ASSERTION_FAILED);
        // case Boolean & Boolean
        runSimplePrimitiveTypesQuery("booleanNull & booleanNull", 
                                     pm, allOddInstances, ASSERTION_FAILED);

        // case Boolean parameter
        runParameterPrimitiveTypesQuery("param & id == 9", 
                                        "Boolean param", Boolean.TRUE,
                                        pm, instance9, ASSERTION_FAILED);
        runParameterPrimitiveTypesQuery("param & id == 9", 
                                        "Boolean param", Boolean.FALSE,
                                        pm, empty, ASSERTION_FAILED);

        // case boolean parameter
        runParameterPrimitiveTypesQuery("param & id == 9", 
                                        "boolean param", Boolean.TRUE,
                                        pm, instance9, ASSERTION_FAILED);
        runParameterPrimitiveTypesQuery("param & id == 9", 
                                        "boolean param", Boolean.FALSE,
                                        pm, empty, ASSERTION_FAILED);

        tx.commit();
    }

    /** */
    void runNegativeTest(PersistenceManager pm) {
        if (debug) logger.debug("\nExecuting positive test BooleanLogicalAND() ...");

        Transaction tx = pm.currentTransaction();
        tx.begin();
        
        try {
            Query q = pm.newQuery(PrimitiveTypes.class, 
                                  "intNotNull & intNotNull");
            Object result = q.execute();
            fail(ASSERTION_FAILED,
                 "Query uisng bitwise & operator should throw JDOUserException.");
        }
        catch (JDOUserException ex) {
            // expected exception
            if (debug) {
                logger.debug("expected exception: " + ex);
            }
        }
        tx.commit();
    }
    
}
