/*
*
* Sample program for use with the Product
* Licensed Materials  - Property of IBM
* 5724-I66
* (c) Copyright IBM Corp.  2006, 2009
*   
*/
package com.ibm.wbit.tel.client.jsf.query;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import com.ibm.bpc.clientcore.ClientException;
import com.ibm.bpc.clientcore.GenericBPCQuery;
import com.ibm.bpe.api.QueryResultSet;
import com.ibm.bpe.clientmodel.BFMConnection;
import com.ibm.wbit.tel.client.jsf.bean.BCInstance;
import com.ibm.wbit.tel.client.jsf.infrastructure.SharedConstants;


/**
 * This class is to query the data base to check the state of process instances.
 * The result will be shown in list, refer to faces-config to see the definition of that query. 
 */
public class BCCheckStateQuery extends GenericBPCQuery implements SharedConstants{
    
    /**
     * Connection to Business Flow Manager to execute the query
     */
    private BFMConnection connection;

  
    /**
     * Executes the query against the BusinessFlowManagerService
     * The BusinessFlowManagerService is determined by the connection property.
     * 
     * @see com.ibm.bpc.clientcore.Query#execute()
     * @throws ClientException: Any exception is caught,nested and rethrown as a ClientException
     */
    public List<BCInstance> execute() throws ClientException {
        ArrayList<BCInstance> result;

        try {
            // Connect to the BFM API
            BFMConnection bfm = getConnection();
            QueryResultSet apiResult = bfm.getBusinessFlowManagerService().query(getSelectClause(), getWhereClause(),
                    getOrderClause(), getThreshold(), null);

            // Iterate over the result returned by the API and
            // and transfrom each row to a bean and add it to the
            // result list.
            result = new ArrayList<BCInstance>(apiResult.size());
            while (apiResult.next()) {
                result.add(transform(apiResult));
            }
        } catch (Exception e) {
            throw new ClientException(NLS_CATALOG, QUERY_FAILED_BUSINESS_CASE_STATUS, null, e);
        }
        return result;       
    }
    
    
    /**
     * Transforms a single row of the result set into a <code>BCInstance</code>
     * 
     * @param apiResult the result set as returned by the query
     * @return <code>BCInstance</code>
     */
    private BCInstance transform(QueryResultSet apiResult) {
        return new BCInstance(apiResult, connection);
        
    }
    
    /**
     * Set new where clause according to passed parameters.
     * 
     * @param templateName name of process tempalte
     * @param customProperties custom properties
     *  
     */
    public void setWhereClause(String templateName, HashMap<String, String> customProperties) {

        StringBuffer whereClause = new StringBuffer();
        whereClause.append("PROCESS_INSTANCE.TEMPLATE_NAME = '");
        whereClause.append(templateName);
        whereClause.append("'");

        if (customProperties != null) {
            Iterator<String> keys = customProperties.keySet().iterator();
            String key;
            Object value;
            int i = 0;
            while (keys.hasNext()) {
                key = keys.next();
                value = customProperties.get(key);
                if (value != null && (((String) value).length() > 0)) {
                    whereClause.append(" AND PROCESS_ATTRIBUTE");
                    whereClause.append(i);
                    whereClause.append(".NAME = '");
                    whereClause.append(key);
                    whereClause.append("' AND PROCESS_ATTRIBUTE");
                    whereClause.append(i);
                    whereClause.append(".VALUE = '");
                    whereClause.append(value.toString());
                    whereClause.append("'");
                    i++;
                }
            }
        }
        setWhereClause( whereClause.toString() );
    }
        
    /**
     * Indicates the type of objects returned by this query
     * 
     * @return
     */
    public String getType() {
        return BCInstance.class.getName();
    }

    /**
     * @return Returns the connection.
     */
    public BFMConnection getConnection() {
        return connection;
    }

    /**
     * @param connection The connection to set.
     */
    public void setConnection(BFMConnection connection) {
        this.connection = connection;
    }

}
