/*
 * WritebackListener.java
 *
 * Copyright © 1994-2004, Oracle. All rights reserved. Oracle grants
 * you ("Licensee") a non-exclusive, royalty-free, worldwide license to use,
 * modify and redistribute this software in source and binary code form, provided
 * that (i) this copyright notice and license appear on all copies of the
 * software; (ii) Licensee does not utilize the software in a manner disparaging
 * to Oracle; and (iii) Licensee does not utilize the software in a manner that
 * violates the terms of any Licensee agreement with Oracle.
 */
package samples.javaclient;

import java.util.ArrayList;
import oracle.dss.dataSource.common.QDRoverride;
import oracle.dss.dataSource.common.QueryAdapter;
import oracle.dss.dataSource.common.CellsSubmittedEvent;
import java.awt.Color;
import java.util.Enumeration;
import java.util.Vector;
import oracle.dss.dataView.managers.RuleManager;
import oracle.dss.rules.DiscriminatorRule;
import oracle.dss.rules.RuleBundle;
import oracle.dss.dataView.managers.ViewStyle;
import oracle.dss.rules.discriminator.QDRDiscriminator;
import oracle.dss.util.QDR;

    public class WritebackListener extends QueryAdapter
    {
        // Error messages contains the list of errors from submitting cells
        public ArrayList m_errorMessages = null;
        // Property to store if the writeback operation was successful
        private boolean m_submitSuccess = true; 
        // Contains the list if invalid QDRs
        private ArrayList m_invalidQDRList = null;
        private BIWriteback m_frame = null;
        
        public WritebackListener(BIWriteback parent){
            super();
            m_frame = parent;
        }
        /*
         * Override of QueryAdapter.cellsSubmitted method
         */
        public void cellsSubmitted(CellsSubmittedEvent e)
        {
            m_errorMessages = new ArrayList();
            // If the writeback process failed then we are going to retrieve the error message set by the
            // writeback engine (or the validator program) for each failed QDR. First check whether the submit 
            // was successful or not.
            if (e.isSubmitSuccess() == false)
            {   
                // set submitSuccess property to FALSE
                setSubmitSuccess(false);
                // get the override QDR collection
                ArrayList qdrCollection = (ArrayList)e.getQDROverrides();
                if (qdrCollection != null)
                {
                    int iSize = qdrCollection.size();   
                    for (int i =0; i < iSize; i++)
                    {
                        QDRoverride qdrOverride = (QDRoverride)qdrCollection.get(i);
                        // get the ones that failed the writeback operation
                        if ( qdrOverride.getWritebackStatus() != QDRoverride.WB_OK )
                        {
                            m_errorMessages.add(qdrOverride.getWritebackError());
                            // save QDRs that failed for validation reasons
                            if (qdrOverride.getWritebackStatus() == QDRoverride.VALIDATION_FAILED)
                            addToInvalidQDRList(qdrOverride);
                        }
                    }
                }
            }
            else
            {
                // set submitSuccess property to TRUE
                setSubmitSuccess(true);
                // clear the invalid QDR list
                if (m_invalidQDRList != null)
                    clearInvalidQDRList();
            }
            // update rules
            updateRules();
        }

        private void addToInvalidQDRList(QDRoverride qdrOverride)
        {
            if (m_invalidQDRList == null)
                m_invalidQDRList = new ArrayList();
            m_invalidQDRList.add(qdrOverride);
        }
        private void clearInvalidQDRList()
        {
            m_invalidQDRList.clear();
        }
        private void setSubmitSuccess(boolean success)
        {
            m_submitSuccess = success;
        }
        public ArrayList getInvalidQDRList()
        {
            return m_invalidQDRList;
        }
        public boolean isSubmitSuccess()
        {
            return m_submitSuccess;
        }

        public ArrayList getErrorMessages()
        {
            return m_errorMessages;
        }
    private void updateRules()
    {
        // If the writeback operation was successful, then remove the RuleBundle responsible for
        // painting invalid cells in red italic font and re-set the vector of RuleBundles on the RuleManager.
        if (isSubmitSuccess())
        {
            RuleManager ruleManager = (RuleManager)m_frame.getCrosstab().getGridViewDatabodyStyleManager();
            // Get the vector of RuleBundles and remove any previously added RuleBundle containing rules
            // for formatting invalid cells.
            Vector ruleBundles = ruleManager.getBundles();
            if (ruleBundles == null)
                ruleBundles = new Vector();
            if ( !ruleBundles.isEmpty() ) 
            {
                Enumeration enum = ruleBundles.elements();
                while (enum.hasMoreElements()) 
                {
                    RuleBundle rb = (RuleBundle)enum.nextElement();
                    if (rb.getID().equals(m_frame.CELLFORMAT_BUNDLE_NAME)) 
                    {
                        ruleBundles.remove(rb);
                        break;
                    }
                }     
            }
            // Set the vector of bundles on the RuleManager.
            ruleManager.setBundles(m_frame.getCrosstab(), ruleBundles);
        }
        // If the writeback operation failed for any reason we try to get the list of invalid QDRs.
        // If there are invalid QDRs, then we will create a new RuleBundle to paint the invalid cells
        // in a distinctive style, with red italic font.
        else
        {
            if (m_invalidQDRList != null)
            {
                // Set up a rule to paint invalid Sales Revenue and Costs cells with red italic font. 
                // First we get the RuleManager object from the crosstabs StyleManager.    
                RuleManager ruleManager = (RuleManager)m_frame.getCrosstab().getGridViewDatabodyStyleManager();
                // Create the new ViewStyle
                ViewStyle dataViewStyle = new ViewStyle(); 
                dataViewStyle.setFontItalic(true);
                dataViewStyle.setForeground(Color.RED);
                Vector ruleBundles = ruleManager.getBundles();
                // Get the vector of RuleBundles and remove any previously added RuleBundle containing rules
                // for formatting invalid cells.
                if (ruleBundles == null)
                    ruleBundles = new Vector();
                if (!ruleBundles.isEmpty()) 
                {
                    Enumeration enum = ruleBundles.elements();
                    while (enum.hasMoreElements()) 
                    {
                        RuleBundle rb = (RuleBundle)enum.nextElement();
                        if (rb.getID().equals(m_frame.CELLFORMAT_BUNDLE_NAME))
                        {
                            ruleBundles.remove( rb );
                            break;
                        }
                    }     
                }   
                // Create a new RuleBundle.
                RuleBundle bundle = new RuleBundle();
                bundle.setID(m_frame.CELLFORMAT_BUNDLE_NAME);
                int isize = m_invalidQDRList.size();
                QDR qdr;
                // Loop through the list of invalid QDRs, create a new rule for each of it and add to the RuleBundle.
                for (int i = 0; i < isize; i++)
                {
                    qdr = new QDR((QDRoverride)m_invalidQDRList.get(i));
                    QDRDiscriminator qdrDisc = new QDRDiscriminator(qdr, QDRDiscriminator.SUPERSET);
                    bundle.addRule(new DiscriminatorRule(qdrDisc, dataViewStyle));              
                }
                // Add this new RuleBundle to the list of bundles then reset the RuleManager.
                ruleBundles.addElement(bundle);
                ruleManager.setBundles(m_frame.getCrosstab(), ruleBundles);
            }
            m_frame.displayErrors();
        }
    }
}