/*
 * WritebackHelper.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.jsp;
import java.awt.Color;
import java.util.ArrayList;

import java.util.Enumeration;
import java.util.List;
import java.util.Vector;
import oracle.dss.dataSource.common.QDRoverride;
import oracle.dss.dataSource.common.Query;
import oracle.dss.dataSource.common.QueryAdapter;
import oracle.dss.dataSource.common.CellsSubmittedEvent;
import oracle.dss.dataView.managers.RuleManager;
import oracle.dss.dataView.managers.ViewStyle;
import oracle.dss.rules.DiscriminatorRule;
import oracle.dss.rules.RuleBundle;
import oracle.dss.rules.discriminator.QDRDiscriminator;
import oracle.dss.thin.beans.crosstab.ThinCrosstab;
import oracle.dss.util.QDR;

public class WritebackHelper extends QueryAdapter
{
    public static final String CELLEDIT_BUNDLE_NAME = "Revenue_Cost";
    public static final String CELLFORMAT_BUNDLE_NAME = "Invalid_cells";
    public static final String REVENUE_ID = "MDM!M_SH_OLAP.SALES.REVENUE"; 
    public static final String COSTS_ID = "MDM!M_SH_OLAP.SALES.COSTS";


    // Error messages contains the list of errors from submitting cells
    public String m_errorMessages = "";
    // Property to store if the JSP session was initialized
    public boolean m_inited = false;
    // 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;
  
/*
 * Override of QueryAdapter.cellsSubmitted method
 */
public void cellsSubmitted(CellsSubmittedEvent e)
{
    // Clear the error messages and the invalid QDR list
    m_errorMessages = new String();
    m_invalidQDRList = new ArrayList();
   
    // Store the status of the writeback operation
    m_submitSuccess = e.isSubmitSuccess();
    
    // 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)
    {
        // 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);
                // Check is the QDR failed the writeback operation
                if ( qdrOverride.getWritebackStatus() != QDRoverride.WB_OK )
                {
                    // The error message is sent from the validation program, or the writeback engine
                    m_errorMessages += (qdrOverride.getWritebackError()) + "<br>";
                    // Save QDRs that failed for validation reasons
                    if (qdrOverride.getWritebackStatus() == QDRoverride.VALIDATION_FAILED)
                    {
                        if (m_invalidQDRList == null)
                            m_invalidQDRList = new ArrayList();
                        m_invalidQDRList.add(qdrOverride);
                    }
                }
            }
        }
    }
  }
  
  // Creates the rules for making editable cells for
  // Sales Revenue and Costs in the Thin Crosstab
  public void createCellEditingRules(ThinCrosstab crosstab)
  {
      // Enable cell editing in thin crosstab
      crosstab.setCellEditingAllowed(true);   
        
      // Set up a rule to edit Sales Revenue and Costs measures. First we get the RuleManager object
      // from the crosstabs StyleManager.
      RuleManager ruleManager = (RuleManager)crosstab.getGridViewDatabodyStyleManager();
      
      ViewStyle dataViewStyle = new ViewStyle(); 
      dataViewStyle.setCellEditStyle(ViewStyle.CELL_EDITABLE);
      // Create two separate QDR object for the two editable measures.
      QDR qdrcost = new QDR("MDM!MEASUREDIMENSION");
      qdrcost.addDimMemberPair("MDM!MEASUREDIMENSION", COSTS_ID);
      QDR qdrrev = new QDR("MDM!MEASUREDIMENSION");
      qdrrev.addDimMemberPair("MDM!MEASUREDIMENSION", REVENUE_ID);

      // Create QDR Discriminators based on thess QDRs.
      QDRDiscriminator qdrDisccost = new QDRDiscriminator(qdrcost, QDRDiscriminator.SUPERSET);
      QDRDiscriminator qdrDiscrev = new QDRDiscriminator(qdrrev, QDRDiscriminator.SUPERSET);
      // Create a new RuleBundle that will contain the two new rule created for the two editable measure.
      RuleBundle bundle = new RuleBundle();
      // Set the name for this rule bundle.
      bundle.setID(CELLEDIT_BUNDLE_NAME);
      bundle.addRule(new DiscriminatorRule(qdrDisccost, dataViewStyle));
      bundle.addRule(new DiscriminatorRule(qdrDiscrev, dataViewStyle));

      // Create a vector of RuleBundles and add our newly created RuleBundle to it.
      Vector ruleBundles = new Vector();
      ruleBundles.addElement(bundle);
      // Set the vector of bundles on the RuleManager.
      ruleManager.setBundles(crosstab, ruleBundles);
  }
  // Update the formatting rules aftre writeback
  // if the writeback was successful, removes the previous formatting rules for invalid cells
  // if the writeback was not successful, formats the invalid cells in red font
  public void updateCellFormattingRules(ThinCrosstab crosstab)
  {
      // 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 (m_submitSuccess)
      {
          RuleManager ruleManager = (RuleManager)crosstab.getGridViewDatabodyStyleManager();
          // Get the vector of RuleBundles and remove any previously added RuleBundle containing rules
          // for formatting invalid cells.
          Vector ruleBundles = ruleManager.getBundles();
          if (!ruleBundles.isEmpty()) 
          {
              Enumeration enum = ruleBundles.elements();
              while (enum.hasMoreElements()) 
              {
                  RuleBundle rb = (RuleBundle)enum.nextElement();
                  if (rb.getID().equals(CELLFORMAT_BUNDLE_NAME)) 
                  {
                      ruleBundles.remove(rb);
                      break;
                  }
              }     
          }
          // Set the vector of bundles on the RuleManager.
          ruleManager.setBundles(crosstab, 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, using red 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)crosstab.getGridViewDatabodyStyleManager();
              // Create the new ViewStyle
              ViewStyle dataViewStyle = new ViewStyle(); 
              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.isEmpty()) 
              {
                  Enumeration enum = ruleBundles.elements();
                  while (enum.hasMoreElements()) 
                  {
                      RuleBundle rb = (RuleBundle)enum.nextElement();
                      if (rb.getID().equals(CELLFORMAT_BUNDLE_NAME))
                      {
                          ruleBundles.remove( rb );
                          break;
                      }
                  }     
              }   
              // Create a new RuleBundle.
              RuleBundle bundle = new RuleBundle();
              bundle.setID(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(crosstab, ruleBundles);
          }
      }
  }

  // Set the initialized flag so that the editing rules can be created only once
  public void setInitialized(boolean init)
  {
        m_inited = init;
  }
  // Indicates whether the WritebackHelper has been initialized
  public boolean isInitialized()
  {
      return m_inited;
  }
  
  // Retrieves the error messages from writeback
  public String getErrorMessages()
  {
      return m_errorMessages;
  }
}