/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 ifc.sdb;

import com.sun.star.sdb.XSingleSelectQueryAnalyzer;
import lib.MultiMethodTest;
import com.sun.star.sdb.XSingleSelectQueryComposer;
import com.sun.star.uno.UnoRuntime;
import lib.StatusException;
import lib.Status;
import com.sun.star.beans.PropertyValue;
import com.sun.star.container.XIndexAccess;

/**
* Testing <code>com.sun.star.sdb.XSingleSelectQueryAnalyzer</code>
* interface methods :
* <ul>
*  <li><code>getQuery()</code></li>
*  <li><code>setQuery()</code></li>
*  <li><code>getFilter()</code></li>
*  <li><code>getStructuredFilter()</code></li>
*  <li><code>getGroup()</code></li>
*  <li><code>getGroupColumns()</code></li>
*  <li><code>getHavingClause()</code></li>
*  <li><code>getStructuredHavingClause()</code></li>
*  <li><code>getOrder()</code></li>
*  <li><code>getOrderColumns()</code></li>

* </ul> <p>
* @see com.sun.star.sdb.XSingleSelectQueryAnalyzer
*/
public class _XSingleSelectQueryAnalyzer extends MultiMethodTest {

    // oObj filled by MultiMethodTest
    public XSingleSelectQueryAnalyzer oObj = null ;

    private String queryString = "SELECT * FROM \"biblio\"";
    
    private XSingleSelectQueryComposer xComposer = null;
    
    /**
     * Recieves the object relations:
    * <ul>
    *  <li><code>XSingleSelectQueryComposer xCompoer</code></li>
    * </ul> <p>
     * @see om.sun.star.sdb.XSingleSelectQueryComposer
     */
    protected void before() {

        xComposer = (XSingleSelectQueryComposer)
                      UnoRuntime.queryInterface(XSingleSelectQueryComposer.class,
                      tEnv.getObjRelation("xComposer"));

        if (xComposer == null) {
            throw new StatusException(Status.failed(
           "Couldn't get object relation 'xComposer'. Test must be modified"));
            
        }
    
    }
    /**
    * call <code>setQuery()</code> once with valid query, once with invalid
    * query. Has ok if only on sceond call <code>SQLException</code> was thrwon
    */
    public void _setQuery() {

        try{
            oObj.setQuery("This is an invalid SQL query");
        } catch (com.sun.star.sdbc.SQLException e){
            log.println("expected Exception. ");
        }
        
        try{
            oObj.setQuery(queryString);
        } catch (com.sun.star.sdbc.SQLException e){
            log.println("unexpected Exception: " + e.toString());
            tRes.tested("setQuery()", false);
        }
        tRes.tested("setQuery()", true);
    }
    
    /**
    * checks of the returned value of <code>getQuery()</code>
    * equals the string which was set by <code>setQuery()</code>
    * <p>
    * required methods:
    *<ul>
    * <li><code>setQuery</code></li>
    *</ul>
    */
    public void _getQuery() {
        this.requiredMethod("setQuery()");

        boolean res = false;
        
        res = oObj.getQuery().equals(queryString);
        
        tRes.tested("getQuery()", res);
    }
    
    
    /**
    * Object relation <code>xComposer</code> set a filter. This filter
    * must returned while calling <code>getFilter</code>
    */
    public void _getFilter() {
        try{
            String filter = "\"Identifier\" = 'BOR02b'";
            xComposer.setFilter(filter);
            tRes.tested("getFilter()", (oObj.getFilter().equals(filter)));
            
        } catch (com.sun.star.sdbc.SQLException e){
            log.println("unexpected Exception: " + e.toString());
            tRes.tested("getFilter()", false);
        }
    }
    
    /**
    * Object relation <code>xComposer</code> set a complex filter with method
    . <code>setFilter</code>. Then <code>getStructuredFilter</code> returns a
    * sequenze of <code>PropertyValue</code> which was set with method
    * <code>setStructuredFilter</code> from <xComposer>.
    * Then test has ok status if <getFilter> returns the complex filter.
    * <p>
    * required methods:
    *<ul>
    * <li><code>setQuery</code></li>
    * <li><code>getFilter</code></li>
    *</ul>
    */
    public void _getStructuredFilter() {
        requiredMethod("setQuery()");
        requiredMethod("getFilter()");
        try{
            oObj.setQuery("SELECT \"Identifier\", \"Type\", \"Address\" FROM \"biblio\" \"biblio\"");
            String complexFilter = "( \"Identifier\" = '1' AND \"Type\" = '4' ) OR ( \"Identifier\" = '2' AND \"Type\" = '5' ) OR ( \"Identifier\" = '3' AND \"Type\" = '6' AND \"Address\" = '7' ) OR ( \"Address\" = '8' ) OR ( \"Type\" = '9' )";
            xComposer.setFilter(complexFilter);
            PropertyValue[][] aStructuredFilter = oObj.getStructuredFilter();
            xComposer.setFilter("");
            xComposer.setStructuredFilter(aStructuredFilter);
            tRes.tested("getStructuredFilter()", (oObj.getFilter().equals(complexFilter)));
            
        } catch (com.sun.star.sdbc.SQLException e){
            log.println("unexpected Exception: " + e.toString());
            tRes.tested("getStructuredFilter()", false);
        } catch (com.sun.star.lang.IllegalArgumentException e){
            log.println("unexpected Exception: " + e.toString());
            tRes.tested("getStructuredFilter()", false);
        }
    }
    
    /**
    * Object relation <code>xComposer</code> set a goup. This group
    * must returned while calling <code>getGroup</code>
    */
    public void _getGroup() {
        try{
            String group = "\"Identifier\"";
            xComposer.setGroup(group);
            tRes.tested("getGroup()", (oObj.getGroup().equals(group)));
            
        } catch (com.sun.star.sdbc.SQLException e){
            log.println("unexpected Exception: " + e.toString());
            tRes.tested("getGroup()", false);
        }
    }
    
    /**
    * Method <code>getGroupColumns</code> retunrs a <code>XIndexAccess</code>
    * Test has ok status if returned value is an useable <code>XIndexAccess</code>
    */
    public void _getGroupColumns() {
        try{
           XIndexAccess xGroupColumns = oObj.getGroupColumns();            
            
           tRes.tested("getGroupColumns()", (xGroupColumns != null && 
                                            xGroupColumns.getCount() == 1 && 
                                        xGroupColumns.getByIndex(0) != null));
            
        } catch (com.sun.star.lang.IndexOutOfBoundsException e){
            log.println("unexpected Exception: " + e.toString());
            tRes.tested("getGroupColumns()", false);
        } catch (com.sun.star.lang.WrappedTargetException e){
            log.println("unexpected Exception: " + e.toString());
            tRes.tested("getGroupColumns()", false);
        }
    }
    
    /**
    * Object relation <code>xComposer</code> set a clause. This clause
    * must returned while calling <code>getHavingClause</code>
    */
    public void _getHavingClause() {
        try{
            String clause = "\"Identifier\" = 'BOR02b'";
            xComposer.setHavingClause(clause);
            tRes.tested("getHavingClause()", (
                                        oObj.getHavingClause().equals(clause)));
            
        } catch (com.sun.star.sdbc.SQLException e){
            log.println("unexpected Exception: " + e.toString());
            tRes.tested("getHavingClause()", false);
        }
    }
    
    /**
    * Object relation <code>xComposer</code> set a clause. This clause
    * must returned while calling <code>getHavingClause</code>
    * <p>
    * required methods:
    *<ul>
    * <li><code>setQuery</code></li>
    * <li><code>getFilter</code></li>
    * <li><code>getStructuredFilter</code></li>
    *</ul>
    */
    public void _getStructuredHavingClause() {
        requiredMethod("setQuery()");
        requiredMethod("getFilter()");
        executeMethod("getStructuredFilter()");
        String complexFilter = "( \"Identifier\" = '1' AND \"Type\" = '4' ) OR ( \"Identifier\" = '2' AND \"Type\" = '5' ) OR ( \"Identifier\" = '3' AND \"Type\" = '6' AND \"Address\" = '7' ) OR ( \"Address\" = '8' ) OR ( \"Type\" = '9' )";
        
        try{
           xComposer.setHavingClause(complexFilter);
           PropertyValue[][] aStructuredHaving = oObj.getStructuredHavingClause();
           xComposer.setHavingClause("");
           xComposer.setStructuredHavingClause(aStructuredHaving);
           tRes.tested("getStructuredHavingClause()", 
                                (oObj.getHavingClause().equals(complexFilter)));
            
        } catch (com.sun.star.sdbc.SQLException e){
            log.println("unexpected Exception: " + e.toString());
            tRes.tested("getStructuredHavingClause()", false);
        }
    }
    
    /**
    * Object relation <code>xComposer</code> set an order. This order
    * must returned while calling <code>getOrder</code>
    */
    public void _getOrder() {
        try{
            String order = "\"Identifier\"";
            xComposer.setOrder(order);
            tRes.tested("getOrder()", (oObj.getOrder().equals(order)));
            
        } catch (com.sun.star.sdbc.SQLException e){
            log.println("unexpected Exception: " + e.toString());
            tRes.tested("getOrder()", false);
        }
    }
    
    /**
    * Method <code>getGroupColumns</code> retunrs a <code>XIndexAccess</code>
    * Test has ok status if returned value is an useable <code>XIndexAccess</code>
    */
    public void _getOrderColumns() {
        try{
            XIndexAccess xOrderColumns = oObj.getOrderColumns();
            tRes.tested("getOrderColumns()", (xOrderColumns != null && 
                                              xOrderColumns.getCount() == 1 && 
                                         xOrderColumns.getByIndex(0) != null));
            
        } catch (com.sun.star.lang.IndexOutOfBoundsException e){
            log.println("unexpected Exception: " + e.toString());
            tRes.tested("getOrderColumns()", false);
        } catch (com.sun.star.lang.WrappedTargetException e){
            log.println("unexpected Exception: " + e.toString());
            tRes.tested("getOrderColumns()", false);
        }
    }
    

}  // finish class _XSingleSelectQueryAnalyzer
