/*
 * 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;

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.pc.mylib.PrimitiveTypes;
import org.apache.jdo.tck.util.BatchTestRunner;

/**
 *<B>Title:</B> Primtive type parameter executed null value
 *<BR>
 *<B>Keywords:</B> query
 *<BR>
 *<B>Assertion ID:</B> A14.6.3-1.
 *<BR>
 *<B>Assertion Description: </B>
 * If a parameter type is specified as a primitive, the parameter value
 * passed to execute() must not be null or a JDOUserException is thrown.
 */

public class PrimitiveParameterPassedAsNull extends QueryTest {

    /** */
    private static final String ASSERTION_FAILED = 
        "Assertion A14.6.3-1 (PrimitiveParameterPassedAsNull) 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(PrimitiveParameterPassedAsNull.class);
    }
    
   /** */
    public void test() {
        pm = getPM();

        try {
            loadPrimitiveTypes(pm);
            runTest(pm);
        }
        finally {
            cleanupDatabase(pm, PrimitiveTypes.class);
            pm.close();
            pm = null;
        }
    }
    
    /** */
    void runTest(PersistenceManager pm) {
        Transaction tx = pm.currentTransaction();
        tx.begin();

        Query q = pm.newQuery(PrimitiveTypes.class, "intNotNull == param");
        q.declareParameters("int param");
        try {
            q.execute(null);
            fail(ASSERTION_FAILED, 
                 "query.execute should throw JDOUserException if the actual " +
                 "value of a primitive type parameter is null");
        }
        catch (JDOUserException ex) {
            if(debug) logger.debug("caught expected exception " + ex);
        }

        tx.commit();
        
    }
    
    
}
