/*
 * BIWriteback.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.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.KeyEvent;
import java.io.IOException;

import java.sql.SQLException;
import java.util.Enumeration;
import java.util.Vector;
import java.util.ArrayList;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.border.EmptyBorder;

import oracle.bali.ewt.border.GrayPane;
import oracle.bali.ewt.button.DialogButtonBar;
import oracle.bali.ewt.button.PushButton;
import oracle.bali.ewt.olaf.ColorScheme;
import oracle.dss.crosstab.Crosstab;

import oracle.dss.crosstab.CrosstabDatabody;
import oracle.dss.dataSource.common.PivotConstants;
import oracle.dss.dataSource.common.Query;
import oracle.dss.dataSource.common.QueryException;
import oracle.dss.dataSource.common.QDRoverride;
import oracle.dss.dataSource.client.QueryManager;

import oracle.dss.dataView.Dataview;
import oracle.dss.dataView.managers.RuleManager;
import oracle.dss.dataView.managers.ViewStyle;

import oracle.dss.datautil.OlapDmlUtil;
import oracle.dss.metadataManager.client.MetadataManager;
import oracle.dss.metadataManager.common.MDDimension;
import oracle.dss.metadataManager.common.MDLevel;
import oracle.dss.metadataManager.common.MDMeasure;
import oracle.dss.metadataManager.common.MDObject;
import oracle.dss.metadataManager.common.MetadataManagerException;
import oracle.dss.metadataManager.common.MM;
import oracle.dss.metadataUtil.MDU;
import oracle.dss.metadataUtil.PropertyBag;
import oracle.dss.rules.DiscriminatorRule;
import oracle.dss.rules.RuleBundle;
import oracle.dss.rules.discriminator.QDRDiscriminator;
import oracle.dss.selection.Selection;
import oracle.dss.selection.step.FamilyLevelStep;
import oracle.dss.selection.step.InvalidStepArgException;
import oracle.dss.selection.step.MemberStep;
import oracle.dss.selection.step.Step;
import oracle.dss.selection.SelectionException;
import oracle.dss.util.QDR;



/**
 * This sample is designed to show how to writeback modified data cells represented as QDRs
 * <P>
 * The BIWriteback class extends BIFrame.  In addition to the connection dialog
 * provided by BIFrame, BIWriteback provides a linked crosstab and graph. 
 * @see BIFrame
 */

public class BIWriteback extends JFrame {


  /////////////////////
  //
  // Member Variables
  //
  /////////////////////

  // Menu items
  private JMenu m_sampleMenu;
  private JCheckBoxMenuItem m_cellEditMenu;
  private JCheckBoxMenuItem m_autoSubmitMenu;
  private JMenuItem m_submitChangesMenu;
  private JMenuItem m_writebackValidatorMenu;
  private BIWritebackPanel m_writebackPanel = null;

  // Default query
  private Query m_query = null;

  // This frame
  protected BIFrame m_frame;
  protected JPanel m_panel;
  protected JDialog  m_messageDialog;
  protected JTextArea m_msg;
  protected String m_sWritebackValidator = null;
  protected WritebackListener m_writebackListener = null;
  private OlapDmlUtil m_olapdmlutil = null;
  
 /////////////////////
  //
  // Constants
  //
  /////////////////////
  private static final String REVENUE_ID = "MDM!M_CS_OLAP.SHAWSALES.AMOUNT_SOLD";
  private static final String COSTS_ID = "MDM!M_CS_OLAP.SHAWSALES.COSTS";
  private static final String MARGIN_ID = "MDM!M_CS_OLAP.SHAWSALES.MARGIN_PERCENT";
  private static final String PRODUCT_ID = "MDM!D_CS_OLAP.SHAWPRODUCTS";
  private static final String PRODUCT_LEVEL = "MDM!D_CS_OLAP.SHAWPRODUCTS.PRODUCTS.L.PRODUCT";
  private static final String GEOGRAPHY_ID = "MDM!D_CS_OLAP.SHAWGEOGRAPHIES";
  private static final String PROMOTION_ID = "MDM!D_CS_OLAP.SHAWPROMOTIONS";
  private static final String CHANNEL_ID = "MDM!D_CS_OLAP.SHAWCHANNELS";
  private static final String TIME_ID = "MDM!D_CS_OLAP.SHAWT_TIME";
  private static final String PRODUCT_NAME = "SHAWPRODUCTS";
  private static final String TIME_NAME = "SHAWT_TIME";
  private static final String VALIDATOR_ID = "CS_OLAP.UTILS!WBVALIDATOR";
  protected static final String CELLFORMAT_BUNDLE_NAME = "Invalid_cells";
  
  protected static final String CELLEDIT_BUNDLE_NAME = "Editable_cells";
  
  private final static String NEWLINE = "\n";

  /////////////////////
  //
  // Constructors
  //
  /////////////////////

  /**
   * Constructor for BIWriteback.
   *
   * @param title The title of the JFrame.
   */
  public BIWriteback(BIFrame parentFrame, String title) {
    super(title);
    m_frame = parentFrame;
    init();
  }

  /////////////////////
  //
  // Protected Methods
  //
  /////////////////////

  /**
   * Initialize the user interface.
   */
  protected void init() {
    try {
  
      JMenuBar menuBar = new JMenuBar();

      // Add the view menu options
      addViewMenu(menuBar);
            
      m_panel = new JPanel();
      m_panel.setLayout(new BorderLayout());
    
      // put all of these into the frame
      setJMenuBar(menuBar);
      getContentPane().removeAll();
      getContentPane().add(m_panel, BorderLayout.CENTER);
  
      // add a listener to listen for the window closing event
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent e) {
          cleanUp();
        }
      });
      // Create a default query for Revenue, Costs and Margin %
      m_query = getDefaultQuery();
      // Create a QueryListener and register with our query
      m_writebackListener = new WritebackListener(this);
      m_query.addQueryListener(m_writebackListener);
      // create a dialog that will display error messages comming from the writeback engine.
      createMessageDialog();
      // Create a linked crosstab-graph on startup
      createLinkedView(this, m_query);
      initEditRules(true);
    }

    catch (Exception exception) {
      m_frame.showExceptionDialog(this, exception);
    }
  }
  /**
   * Creates and returns a default query.  The Query will be based on Revenue, Costs and Margin %
   * in the CS_OLAP Schema
   *
   * @return the default Query
   */
  protected Query getDefaultQuery () {
    String[] strMeasures = {REVENUE_ID, COSTS_ID, MARGIN_ID};
    m_query = m_frame.getQueryManager().createQuery();   
    try {
        m_query.initCubeQuery(strMeasures, null);
    }    
    catch (MetadataManagerException mme) {
        m_frame.showExceptionDialog(this, mme);
        return null;
    }
    catch (InvalidStepArgException isae) {
      m_frame.showExceptionDialog(this, isae);
    }
    catch (QueryException qe) {
      m_frame.showExceptionDialog(this, qe);
    }
    catch (SelectionException se) {
      m_frame.showExceptionDialog(this, se);
    }
    return m_query;
  }

  private void initEditRules(boolean viewEditable)
  {
        Crosstab crosstab = m_writebackPanel.getCrosstab();
        RuleManager ruleManager = (RuleManager)crosstab.getGridViewDatabodyStyleManager();
        ViewStyle dataViewStyle = new ViewStyle(); 
        
        dataViewStyle.setBackground(Color.lightGray);
        dataViewStyle.setFontItalic(true);
        
        Vector ruleBundles = ruleManager.getBundles();
        // Get the vector of RuleBundles and remove any previously added RuleBundle containing rules
        // for formatting non-editable 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(CELLEDIT_BUNDLE_NAME))
                {
                    ruleBundles.remove( rb );
                    break;
                }
            }     
        }   
        // Create a new RuleBundle.
        RuleBundle bundle = new RuleBundle();
        
        // if the view is non editable, then create a separate QDR object for all three measures.
        // otherwise create only for revenue and cost. Paint the non-editable qdr's with gray color
        // to mark them visualy non-editable. 
        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);
                
        // Set the name for this rule bundle.
        bundle.setID(CELLEDIT_BUNDLE_NAME);
        bundle.addRule(new DiscriminatorRule(qdrDisccost, dataViewStyle));
        bundle.addRule(new DiscriminatorRule(qdrDiscrev, dataViewStyle));
        if (! viewEditable)
        {
            QDR qdrmrg = new QDR("MDM!MEASUREDIMENSION");
            qdrmrg.addDimMemberPair("MDM!MEASUREDIMENSION", MARGIN_ID);    
            QDRDiscriminator qdrDiscmrg = new QDRDiscriminator(qdrmrg, QDRDiscriminator.SUPERSET);
            bundle.addRule(new DiscriminatorRule(qdrDiscmrg, dataViewStyle));
        }
      
        ruleBundles.addElement(bundle);
        // Set the vector of bundles on the RuleManager.
        ruleManager.setBundles(crosstab, ruleBundles); 
  }
  /**
   * This method cleans up before returning to the main menu
   */
  protected void cleanUp() {
    
    // Free resources associated with the menu items
    
    m_cellEditMenu = null;
    m_autoSubmitMenu = null;
    m_submitChangesMenu = null;
    m_writebackValidatorMenu = null;
    
    // Free resources associated with any previously linked panel
    
    if (m_writebackPanel != null) {
      // Remove the panel
      m_panel.remove(m_writebackPanel);
      m_panel.invalidate();
      m_panel.validate();
      m_panel.repaint();

      // Free any panel resources
      m_writebackPanel.free();
      m_writebackPanel = null;
    }
    m_messageDialog = null;
    m_msg = null;
    // Release default query
    if (m_query != null) {
      m_query.close();
      m_query = null;
    }
    dispose();
    }

  /**
   * Creates linked crosstab and graph views based on the <code>Query</code>.
   *
   * @param frameParent   The Frame that the panel is inserted into.
   * @param query         The Query associated with the linked view.
   */
  protected void createLinkedView(Frame frameParent, Query query) {

    // Free resources associated with any previously linked panel
    if (m_writebackPanel != null) {
      m_panel.remove(m_writebackPanel);
      m_writebackPanel.free();
      m_writebackPanel = null;
    }

    try {
      // Create a new BIWritebackPanel
      m_writebackPanel = new BIWritebackPanel(frameParent, query);
    }

    catch (Exception exception) {
      m_frame.showExceptionDialog(this, exception);
    }
    // change the status of PRODUCT and TIME dimensions
    modifyQuery(m_writebackPanel.getCrosstab());
    // change the default layout
    changeLayout();
    m_writebackPanel.setVisible(true);
    m_writebackPanel.revalidate();
    m_panel.add(m_writebackPanel, BorderLayout.CENTER);
    m_panel.revalidate();
  }
  private void modifyQuery(Dataview crosstab)
  {
    try{
      // Retrieve Metadata measure unique ID 
        MDMeasure firstMeasure = m_frame.getMetadataManager().getMeasure(MM.UNIQUE_ID,  REVENUE_ID);

        // Get the Dimensions for the measure
        MDDimension[] mdDimensions = firstMeasure.getDimensions();

        // Cycle over the dimensions for the measure    
        Selection sels [] = new Selection[2];
        for (int i = 0; i < mdDimensions.length; i++) {
      
            // Retrieves the name of the dimension
            String strDimensionName = mdDimensions[i].getName();
            
            if (strDimensionName.equals(PRODUCT_NAME))
            {
                // Retrieves the Hierarchy ID for the Dimension
                String strDimensionHierarchy = mdDimensions[i].getDefaultHierarchy().getUniqueID(); 
                sels[0] = new Selection(PRODUCT_ID);
                sels[0].setHierarchy (strDimensionHierarchy);
                MemberStep mStep = new MemberStep (PRODUCT_ID);
                mStep.setHierarchy(strDimensionHierarchy);
                mStep.addMember ("201", PRODUCT_LEVEL);
                mStep.addMember ("202", PRODUCT_LEVEL);
                mStep.setAction(Step.SELECT);
                sels[0].addStep(mStep);    
            }
            if (strDimensionName.equals(TIME_NAME))
            {
                // Retrieves the Hierarchy ID for the Dimension
                String strDimensionHierarchy = mdDimensions[i].getDefaultHierarchy().getUniqueID(); 
                MDLevel[] mdLevels = mdDimensions[i].getDefaultHierarchy().getLevels();
                String level_2 = mdLevels[2].getUniqueID();
                String level_1 = mdLevels[1].getUniqueID();
                Vector levels = new Vector ();
                levels.addElement (level_2);
                Vector levels1 = new Vector();
                levels1.addElement(level_1);
                sels[1] = new Selection(TIME_ID);
                sels[1].setHierarchy (strDimensionHierarchy);
                Vector familyValues = new Vector ();
                familyValues.addElement ("1805");
                FamilyLevelStep fStep = new FamilyLevelStep(TIME_ID, strDimensionHierarchy, levels, familyValues, false);                
                fStep.setFamilyValuesLevels(levels1);
                fStep.setAction(Step.SELECT);
                sels[1].addStep (fStep); 
            }
        }
        m_query.applySelections(sels);
    }
    catch (MetadataManagerException mme) {
        m_frame.showExceptionDialog(this, mme);
    }
    catch (InvalidStepArgException isae) {
        m_frame.showExceptionDialog(this, isae);
    }
    catch (QueryException qe) {
        m_frame.showExceptionDialog(this, qe);
    }
    catch (SelectionException se) {
        m_frame.showExceptionDialog(this, se);
    }
  }
  private void changeLayout()
  {
    try{
        m_query.swap(GEOGRAPHY_ID, "MDM!MEASUREDIMENSION");
        m_query.swap(TIME_ID, CHANNEL_ID);
        m_query.pivot(GEOGRAPHY_ID, PRODUCT_ID, PivotConstants.PIVOT_AFTER);
    }
    catch (InvalidStepArgException isae) {
            m_frame.showExceptionDialog(this, isae);
    }
    catch (MetadataManagerException mme) {
        m_frame.showExceptionDialog(this, mme);
    }
    catch (SelectionException se) {
      m_frame.showExceptionDialog(this, se);
    }        
    catch (QueryException qe) {
      m_frame.showExceptionDialog(this, qe);
    }
  }
  /**
   * Retrieves the current frame.
   *
   * @return <code>Frame</code> which represents the current frame.
   */
  protected Frame getFrame() {
    return this;
  }

  /////////////////////
  //
  // Private Methods
  //
  /////////////////////

  /**
   * Adds the view menu to the specified <code>JMenuBar</code>.
   *
   * @param menuBar       Menu bar to attach view menu to.
   *
   * @throws Exception
   */
  private void addViewMenu(JMenuBar menuBar) throws Exception {
    // View menu
    m_sampleMenu = new JMenu("Edit Data");
    m_sampleMenu.setMnemonic(KeyEvent.VK_E);
    menuBar.add(m_sampleMenu);
    
    //Cells are editable
    m_cellEditMenu = new JCheckBoxMenuItem("Set Cells Editable");
    // By default the cells are editable in this example
    m_cellEditMenu.setState(true);
    m_cellEditMenu.setMnemonic(KeyEvent.VK_D);

    // Submit is Autosubmit
    m_autoSubmitMenu = new JCheckBoxMenuItem("Set Autosubmit");
    // By default the cells submit mode is Auto
    m_autoSubmitMenu.setState(false);
    m_autoSubmitMenu.setMnemonic(KeyEvent.VK_A);
    
    // Submit Changes menu
    m_submitChangesMenu = new JMenuItem("Submit Changes");
    m_submitChangesMenu.setMnemonic(KeyEvent.VK_S);

    // Writeback Validator registration
    m_writebackValidatorMenu = new JMenuItem("Register Writeback Validator...");
    m_writebackValidatorMenu.setMnemonic(KeyEvent.VK_V);


    // Add each menu item to menu.
    m_sampleMenu.add(m_cellEditMenu);
    m_sampleMenu.add(m_autoSubmitMenu);
    // Add a separator
    m_sampleMenu.addSeparator();
    m_sampleMenu.add(m_submitChangesMenu);
    m_sampleMenu.add(m_writebackValidatorMenu);

    // Add Listener to m_cellEditMenu
    m_cellEditMenu.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent event) {
        if (m_writebackPanel.getCrosstab() != null)
            m_writebackPanel.getCrosstab().setCellEditingAllowed(m_cellEditMenu.getState());
            m_writebackValidatorMenu.setEnabled(m_cellEditMenu.getState());
            initEditRules(m_cellEditMenu.getState());
      }
    });

    // Add Listener to m_autoSubmitMenu
    m_autoSubmitMenu.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent event) {
        if (m_writebackPanel.getCrosstab() != null)   
                m_query.setAutoSubmit(m_autoSubmitMenu.getState());
                m_submitChangesMenu.setEnabled(!m_autoSubmitMenu.getState());
      }
    });

    // Add Listener to m_submitChangesMenu
    m_submitChangesMenu.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent event) {
        Crosstab crosstab = m_writebackPanel.getCrosstab();
        try
        {
            // The edited data cells will be passed to the writeback engine as a list of QDRoverride objects.
            crosstab.getModel().getDataAccess().submitChanges(); 
            if (m_writebackListener.isSubmitSuccess())
                runModel();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
      }
    });

    // Add Listener to m_writebackValidatorMenu
    m_writebackValidatorMenu.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent event) {
        setupWritebackValidator();
      }
    });
  }
  private void setupWritebackValidator() 
    {
        final JDialog writebackValidatorDialog = new  JDialog(this,"Set Writeback Validator", true);
        final Query myQuery = m_query;
        JComponent content = (JComponent)writebackValidatorDialog.getContentPane();
        content.setLayout(new BorderLayout(0,6));
        content.setBorder(new EmptyBorder( new Insets( 6, 6, 6, 6 ) ));
        content.setBackground(UIManager.getColor(oracle.bali.ewt.olaf.ColorScheme.DARK_LOOK));
        JPanel topPanel = new JPanel();
        topPanel.setLayout(new GridLayout(1, 1, 10, 10));
        topPanel.setBorder( new EmptyBorder( new Insets( 10, 10, 10, 10 ) ) );
        GrayPane gp = new GrayPane(topPanel);
        writebackValidatorDialog.getContentPane().add(gp, BorderLayout.CENTER);
        topPanel.setLayout( new GridLayout(2, 1, 10, 10));
        JPanel p1 = new JPanel();
        JLabel first = new JLabel("Enter OLAP DML Validation Program Name:  ");
        p1.add(first);
        final JTextField textfield1 = new  JTextField(20);
        m_sWritebackValidator = "CS_OLAP.UTILS!WBVALIDATOR";
        if (m_sWritebackValidator != null)
           textfield1.setText(m_sWritebackValidator);
        p1.add(textfield1);
        topPanel.add(p1);

        PushButton okButton        = new PushButton("OK");
        PushButton cancelButton    = new PushButton(" Cancel ");
        JPanel buttonPanel = new JPanel();
        okButton.setLeftmost(true);
        okButton.setRightmost(true);
      	buttonPanel.add(okButton, DialogButtonBar.CONSTRAINT_YES);
        okButton.addActionListener(new ActionListener(){
	       public void actionPerformed(ActionEvent evt){
             m_sWritebackValidator = textfield1.getText();
             m_query.setWritebackValidator(m_sWritebackValidator);
             writebackValidatorDialog.setVisible(false);
       			 writebackValidatorDialog.dispose();
          }
       } );
      cancelButton.setLeftmost(true);
      cancelButton.setRightmost(true);
    	buttonPanel.add(cancelButton,DialogButtonBar.CONSTRAINT_CANCEL);
      cancelButton.registerKeyboardAction(new ActionListener() {
      public void actionPerformed(ActionEvent event) {
          writebackValidatorDialog.setVisible(false);
  				writebackValidatorDialog.dispose();
        }
      },KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0),
        JComponent.WHEN_IN_FOCUSED_WINDOW);
        cancelButton.addActionListener(new ActionListener(){
	       public void actionPerformed(ActionEvent evt){
	            writebackValidatorDialog.setVisible(false);
                writebackValidatorDialog.dispose();

            }
        } );
        writebackValidatorDialog.getContentPane().add(buttonPanel,BorderLayout.SOUTH);
        writebackValidatorDialog.pack();
        writebackValidatorDialog.show();
      
    }
    
    protected void displayErrors()
    {
        ArrayList errorList = m_writebackListener.getErrorMessages();
        if (errorList != null)
        {
            int size = errorList.size();
            m_msg.setText(null);
            for ( int i = 0; i < size; i++ )
            {
                m_msg.append((String)errorList.get(i) + NEWLINE);
            }
            m_messageDialog.show();
        }
    }
    private void createMessageDialog()
    {
        m_messageDialog = new  JDialog(this,"Writeback failed", true);
        Query myQuery = m_query;
        JComponent content = (JComponent) m_messageDialog.getContentPane();
        content.setLayout(new BorderLayout(0,6));
        content.setBorder(new EmptyBorder( new Insets( 6, 6, 6, 6 ) ));
        content.setBackground(UIManager.getColor(ColorScheme.DARK_LOOK));
        
        JPanel topPanel = new JPanel();
        
        topPanel.setLayout(new GridLayout(1, 1, 10, 10));
        topPanel.setBorder( new EmptyBorder( new Insets( 10, 10, 10, 10 ) ) );
        GrayPane gp = new GrayPane(topPanel);
        m_messageDialog.getContentPane().add(gp, BorderLayout.CENTER);
        topPanel.setLayout( new GridLayout(1, 1, 10, 10));
        
        JPanel messagePanel = new JPanel();
        m_msg = new JTextArea(10, 30);
        m_msg.setEditable(false);
        JScrollPane scrollbox = new JScrollPane(m_msg, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
                                                        JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
        messagePanel.add(scrollbox);
        topPanel.add(messagePanel);
        
        JPanel buttonPanel = new JPanel();
        PushButton okButton        = new PushButton("Close");
      	buttonPanel.add(okButton, DialogButtonBar.CONSTRAINT_YES);
        okButton.setLeftmost(true);
        okButton.setRightmost(true);
        okButton.addActionListener(new ActionListener(){
	       public void actionPerformed(ActionEvent evt){
             m_messageDialog.setVisible(false);
          }
       } );
        m_messageDialog.getContentPane().add(buttonPanel,BorderLayout.SOUTH);
        m_messageDialog.pack();
    }
    protected Crosstab getCrosstab()
    {
        return m_writebackPanel.getCrosstab();
    }
    private void runModel() throws Exception 
    {
        if (m_olapdmlutil == null)
          m_olapdmlutil = new OlapDmlUtil( m_query.getMetadataManager() );
        m_olapdmlutil.executeCommand( "call CS_OLAP.UTILS!CALC_MARGIN" );
        m_query.refresh(true);
    }
}
