/*
 * DimensionExplorer.java
 *
 * Copyright (c) 2003, Oracle Corporation. 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.analyzer;
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.datatransfer.StringSelection;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragSource;
import java.awt.dnd.DragSourceDragEvent;
import java.awt.dnd.DragSourceDropEvent;
import java.awt.dnd.DragSourceEvent;
import java.awt.dnd.DragSourceListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import java.lang.String;

import java.util.Vector;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;

import oracle.bali.ewt.text.MultiLineLabel;
import oracle.bali.ewt.text.WordWrapper;

import oracle.dss.dataSource.client.QueryClient;
import oracle.dss.datautil.QueryAccess;
import oracle.dss.datautil.QueryAccessDimensionModel;
import oracle.dss.datautil.gui.dimensionList.OLAPDimensionListPanel;
import oracle.dss.metadataManager.client.MetadataManager;
import oracle.dss.metadataManager.common.MDDimension;
import oracle.dss.selection.Selection;
import oracle.dss.selection.step.InvalidStepArgException;
import oracle.dss.selection.step.MemberStep;
import oracle.dss.selection.step.Step;
import oracle.dss.util.LayerMetadataMap;

import oracle.jdeveloper.layout.VerticalFlowLayout;

/**
 * The Members tab in the Sidebar.
 * This Explorer presents an OLAPDimensionListPanel that displays the
 * members of a dimension.
 * Users can select the members and add them to the selection for that
 * dimension in the active worksheet.
 * Or, users can replace the current selection in the worksheet with the 
 * members that are selected in the dimension list.
 * <p>
 * The dimension list displays the members of one dimension.
 * This Explorer presents a combo box of different dimensions that are available,
 * from which users choose the dimension they want to work with.
 * <p>
 * This Explorer maintains an internal list of dimensions that are in the
 * queries of open views in the Analyzer application.
 * This class uses a vector of {@link DimensionInfo} objects, which store 
 * information about each dimension, such as its name, its unique ID, and
 * so on.
 * <p>
 * When a user opens or creates a worksheet, the application passes the
 * query of the worksheet to this Explorer. 
 * If the query has dimensions whose information is not already in the vector
 * of DimensionInfo objects, then this Explorer adds a DimensionInfo to the 
 * vector. See {@link #addDimensions}.
 * For dimensions that are in the list, this Explorer increments a usage count.
 * When a user closes a worksheet, the application decrements the count for
 * each dimension in the query of the closed worksheet. 
 * When the count reaches 0, the Explorer removes the DimensionInfo from
 * the vector. See {@link #removeDimensions}.
 * <p>
 * The {@link #setQuery} method specifies the query whose selections will be changed
 * by user actions in this Explorer.
 * The Analyzer application calls setQuery whenever the user selects a 
 * worksheet to make it the active worksheet.
 * <p>
 * The {@link #applyDimListSelection} method applies the dimension members that
 * are selected in this Explorer to the selection for the dimension in the
 * active query.
 * 
 */
public class DimensionExplorer extends JPanel implements ActionListener, 
                          DragGestureListener, DragSourceListener  {

  /**
   * Is this Explorer visible?
   */
  private boolean isExplorerVisible = false;                         
  /**
   * "Add selected members" text for the actions combo box.
   */
  private static final String ADD = "Add selected members";
  /**
   * "Replace with selected memebers" text for the actions combo box.
   */
  private static final String REPLACE = "Replace with selected members";
  /**
   * Label for the actions combo box: "Update selected document:"
   */
  private static final String OPTION_TITLE = "Update selected document:";    
  /**
   * Text for the Go button.
   */
  private static final String APPLY_BUTTON_TEXT = "Go";
  /**
   * DragSource object for drag-and-drop support.
   */
  private DragSource m_dragSource;
  /**
   * The active query, which is modified when the user clicks Go or drags
   * members to a worksheet.
   */
  private QueryClient m_query;
  /**
   * The MetadataManager for this Explorer.
   * This is the application's MetadataManager.
   */
  private MetadataManager m_metadataManager;
  /**
   * The dimension list that this Explorer displays.
   */
  private OLAPDimensionListPanel m_dimList = null;
  /**
   * Drop-down list of dimensions whose members to display.
   */
  private JComboBox m_dimensionCombo = new JComboBox();
  /**
   * Drop-down list for what to do with the selected members.
   * Users can either add members to the current selection or
   * replace the current selection with the members.
   */
  private JComboBox actions = new JComboBox();
  /**
   * Text to display when no worksheets are open.
   */
  private String m_notAvailableText = "Dimension member lists are only available when a document is open.";
  /**
   * Instruction text.
   * Currently not displayed.
   */
  private static final String DIMENSION_DESCRIPTION = "Select dimension members.  Then, use the arrow button to update the document.";
  /**
   * Label for m_notAvailableText.
   * This object makes it possible to set font attributes.
   */
  private MultiLineLabel notAvail = new MultiLineLabel(); 
  /**
   * The parent frame for this Explorer.
   * (The Analyzer class.)
   */
  private Frame m_parentFrame;
  /**
   * Go button.
   */
  private JButton m_applyButton = new JButton();
  /**
   * Panel for the dimension list.
   */
  private JPanel m_middlePanel = new JPanel();
  /**
   * Layout constraintes for the dimension list.
   */
  private GridBagConstraints m_dimListConstraints;
  /**
   * Vector for {@link DimensionInfo} objects.
   * @see #addDimensions
   * @see #removeDimensions
   */
  private Vector m_dimensions = new Vector();
  

  /**
   * Constructor.  Sets the DimensionExplorer to "Not Available" state.
   * @param parentFrame The Analyzer main application frame.
   */
  public DimensionExplorer(Frame parentFrame) {
    super();
    setLayout(new BorderLayout());
    m_parentFrame = parentFrame;

    // Explorer is initially "disabled"
    setNotAvailable();
    
    // Add listener to button that updates the query
    m_applyButton.addActionListener(this);
    
  }

  /**
   * Indicates whether a dimension is in the list of dimensions.
   * 
   * @param dimensionUniqueID The unique ID for the dimension.
   * @return <code>true</code> if the dimension is in the list,
   *         <code>false</code> if it is not.
   */
  public boolean inDimensionList (String dimensionUniqueID) {
      int index = getDimensionIndex(dimensionUniqueID);
      if (index == -1)
        return false;
      else 
        return true;    
  }

  /**
   * Gets the index for a dimension in the list of dimensions.
   * The index represents the position of the dimension in the m_dimensions
   * vector and in the m_dimensionCombo drop-down.
   * 
   * @param dimensionUniqueID The unique ID for the dimension whose index you want.
   * @return The index of the dimension in the list of dimensions, or -1
   *         if the dimension is not in the list.
   *         
   * @see #m_dimensions
   * @see #m_dimensionCombo
   */
  public int getDimensionIndex (String dimensionUniqueID) {
    
    int index = -1;
      
    for (int i = 0; (i < m_dimensions.size() && index == -1); i++)  {
        if (dimensionUniqueID.equalsIgnoreCase(((DimensionInfo) m_dimensions.get(i)).getUniqueID()))  
          index = i;
    }

    return index;

  }

  /**
   * Gets the drag source for this Explorer.
   * 
   * @return The drag source.
   */
  public DragSource getDragSource() {
     return m_dragSource;
   }

   /**
    * Sets the drag source for this Explorer.
    * 
    * @param dragSource The drag source to set on this Explorer.
    */
   public void setDragSource (DragSource dragSource) {
     m_dragSource = dragSource;
   }

  /** 
   * Creates an OLAPDimensionListPanel for a dimension.  
   * An OLAPDimensionListPanel supports the display of hierarchies.
   * This method shows how to construct the panel and how to set it up as a
   * drag source component.
   * <p>
   * The initializeExplorer method calls this method to create a dimension
   * list for the default dimension.
   * After that, this method is called to create a dimension list for the
   * dimension that is selected in the combo box.
   *
   * @param dimension The index of the dimension whose members to display. 
   *                  The index is the index in the m_dimensions vector and in 
   *                  m_dimensionCombo.
   *                  
   * @see #m_dimensions
   * @see #m_dimensionCombo
   * @see #initializeExplorer
   */
  private OLAPDimensionListPanel getDimList(int dimension) {

    OLAPDimensionListPanel newDimList = null;

    // Get the query object embedded in the crosstab
    QueryClient query = (QueryClient) getQuery (); 

    // QueryAccess is a class that enables application code to modify a query's
    // selection without affecting the view.  This means that you do not need
    // to clone the Dimension selection if the OLAPDimensionList is based on the 
    // same query. 
    
    //Grant access to the Query using the queryAccess class
    QueryAccess queryAccess = query.createQueryAccess();    

    // Create the Query Access Dimension model that features in the OLAP Dimension List Panel.
    // This includes Metadata Manager unique ID's for the dimension and Hierarchy

    // The Query Access Dimension Model specifies the dimension information for the OLAPDimensionListPanel
    String uniqueID = ((DimensionInfo)m_dimensions.get(dimension)).getUniqueID();
    String hier = ((DimensionInfo)m_dimensions.get(dimension)).getHierarchy();
    // nulls--no need for LayoutAccess, because we only have one dimension
    // also not setting an error handler
    QueryAccessDimensionModel qadm = 
                new QueryAccessDimensionModel(queryAccess, null, null,
                    uniqueID, hier, getMetadataManager());

    // Create the OLAP Dimension List by passing the Query Access Dimension 
    // Model created above.
    newDimList = new OLAPDimensionListPanel(m_parentFrame, qadm);  

    /*
     * Make the dimension list a drag source
     */
    newDimList.getDimensionList().setDragEnabled(false);
    DragSource m_dragSource = DragSource.getDefaultDragSource();

    // creating the recognizer is all that's necessary - it
    // does not need to be manipulated after creation
    m_dragSource.createDefaultDragGestureRecognizer(
       newDimList.getDimensionList(), // component where drag originates
       DnDConstants.ACTION_COPY_OR_MOVE, // actions
       this); // drag gesture listener
    
    newDimList.setToolbarVisible(true);
   
    return newDimList;

  }

  /**
   * Applies the selected dimension members to the related query.
   * This method checks to see whether the user has selected any 
   * dimension members, and whether the user has chosen adding or 
   * replacing in the actions JComboBox.
   * <p>
   * If the user has selected adding, then this method adds the selected
   * members to the members in the selection.
   * <p>
   * If the user has selected replacing, then this method removes all steps
   * from the selection and adds the selected members to the selection.
   * 
   * @see #actions
   */
  public void applyDimListSelection() {

    // Return if there is nothing selected
    if (m_dimList.isSelectionEmpty()) 
      return;

    // Get the Query object for the Crosstab. 
    QueryClient query = getQuery();

    // Get the Selection object for the selected dimension. 
    int selected = m_dimensionCombo.getSelectedIndex();
    String dimension = ((DimensionInfo)m_dimensions.get(selected)).getUniqueID();
    Selection selection = query.findSelection(dimension);

   //  If the user is REPLACING the selection, we remove all steps and replace
   //  it with a new MEMBERSTEP.  If the user is ADDING to the selection, we 
   //  simply add the MEMBERSTEP to the existing list of steps.

    // Get Member step for the selected Dimension that features in the list
    MemberStep step = m_dimList.getSelectedMemberStep();
    
    try {        
        if (actions.getSelectedIndex() == 1) // ADD Dimension members
          // Add to the selection step
          step.setAction(Step.ADD);
        else {
          // Remove all existing selection step(s)
          selection.removeAllSteps();

          // Add to the New selection step(s)
          step.setAction(Step.SELECT);
          }
      }
    catch (InvalidStepArgException e) {
    }
   
    // Add the selection step to the list of steps and apply the selection
    // to the query.
    selection.addStep(step);

    try {
        query.applySelection(selection);
    }
    catch (Exception e) {
    }
      
  }

  /**
   * Sets the active query for this Explorer.
   * Members that are selected in this Explorer will be applied to this query.
   * <p>
   * The addDimensions method calls this method.
   * The Analyzer.addWorksheet method calls addDimensions when the user
   * opens or creates a worksheet.
   * The Analyzer.setActiveWorksheet method calls this method when the user
   * selects a worksheet.
   * 
   * @param query The query for this Explorer.
   * 
   * @see #addDimensions
   * @see Analyzer#addWorksheet
   * @see Analyzer#setActiveWorksheet
   */
  public void setQuery (QueryClient query) {
    m_query = query;
  }

  /**
   * Gets the query for this Explorer.
   * This is the query whose selections are altered by the user's interaction 
   * with this Explorer.
   * 
   * @return The query for this Explorer.
   */
  public QueryClient getQuery () {
    return m_query;
  }

  /**
   * Sets the MetadataManager for this Explorer.
   * Analyzer.initializeUI calls this method to set the application's
   * MetadataManager on this Explorer.
   * This Explorer uses the MetadataManager to get information about
   * the dimensions in the query.
   * 
   * @param metadataManager The MetadataManager that the application uses.
   * 
   * @see #addDimensions
   */
  public void setMetadataManager(MetadataManager metadataManager)  {
    m_metadataManager = metadataManager;
  }

  /**
   * Gets the MetadataManager that this Explorer uses.
   * This should be the same MetadataManager that the rest of the application
   * uses.
   * 
   * @return The MetadataManager for this Explorer.
   */
  public MetadataManager getMetadataManager() {
    return m_metadataManager;
  }

  /**
   * Displays a Not Available message in the Explorer.  This is called when there is
   * not a valid query to operate on.
   */
  private void setNotAvailable() {
    isExplorerVisible = false;
    notAvail.setFont(new Font("Dialog", 0, 12));
    notAvail.setText(m_notAvailableText);
    notAvail.setTextWrapper(WordWrapper.getTextWrapper());
    this.removeAll();
    this.add(notAvail);       
    this.invalidate();
    this.validate();
    this.repaint();
  }

  /**
   *  Initializes the user interface for this Explorer.
   *  This method:
   *  <ol><li>Creates a dimension list for a default dimension.</li>
   *  <li>Sets the combo box of dimensions to the default dimension.</li>
   *  <li>Adds a listener to the combo box.</li>
   *  <li>Adds the Go button.</li>
   *  <li>Sets the choices in the Add or Replace combo box.</li>
   *  <li>Lays out all the components.</li>
   *  </ol>
   */
  public void initializeExplorer() {   
    // Create a dimension list for a default dimension
    m_dimList = getDimList(0);

    // Initialize the list of dimensions
    m_dimensionCombo.setSelectedIndex(0);

    // Add listener to the combo box
    m_dimensionCombo.addActionListener(this);

    // Create the button that will apply the selection
    m_applyButton.setText(APPLY_BUTTON_TEXT);
    actions.removeAllItems();
    actions.addItem(REPLACE);
    actions.addItem(ADD);
    actions.setSelectedIndex(0);

    /*
     * Add the objects to the panels
     */
    // top panel will contain the description and dimension drop-down
    JPanel topPanel = new JPanel();
    topPanel.setLayout(new VerticalFlowLayout());
    topPanel.add(m_dimensionCombo, null);

    m_dimList.setBorder(BorderFactory.createEmptyBorder(2,2,2,2));
    m_middlePanel.removeAll();
    m_middlePanel.setLayout(new BorderLayout());
    m_middlePanel.add(m_dimList, BorderLayout.CENTER);

    JPanel bottomPanel = new JPanel(new GridBagLayout());
    JLabel actionLabel = new JLabel(OPTION_TITLE);
    bottomPanel.add(actionLabel, new GridBagConstraints(0,0,2,1,1,1,
                    GridBagConstraints.WEST, GridBagConstraints.NONE, 
                    new Insets(4, 4, 4, 4), 0,0));
    bottomPanel.add(actions, new GridBagConstraints(0,1,1,1,1,1,
                    GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, 
                    new Insets(0,4, 0, 4), 0,0));                    
    bottomPanel.add(m_applyButton, new GridBagConstraints(1,1,1,1,0,0,
                    GridBagConstraints.EAST, GridBagConstraints.NONE, 
                    new Insets(0,4, 0, 4), 0,0));                                        
    
    this.removeAll();    
    this.add(topPanel, BorderLayout.NORTH);
    this.add(m_middlePanel, BorderLayout.CENTER);
    this.add(bottomPanel, BorderLayout.SOUTH);
    this.invalidate();
    this.validate();
    this.repaint();

    isExplorerVisible = true;
    
  }

  /**
   * Updates the user interface for this Explorer.
   * This is normally called when the user selects a dimension in the 
   * combo box.
   * <p>
   * This method removes the current dimension list and sets a dimension
   * list for the newly selected dimension.
   */
  private void updateExplorer () {
    if (m_dimList == null)
      return;

    // remove the current dimension list
    m_middlePanel.remove(m_dimList);

    // add a new one
    int dimension = m_dimensionCombo.getSelectedIndex();
    m_dimList = getDimList(dimension);

    m_middlePanel.add(m_dimList, m_dimListConstraints);
    m_middlePanel.invalidate();
    m_middlePanel.validate();
    
  }

  /**
   * Removes unused dimensions from the list of dimensions.
   * This method decrements the usage counter for each dimension.  
   * The usage counter tracks the number of views whose queries include
   * this dimension.  If the count is zero
   * after decrementing, then this method removes the dimension from the list.
   * <p>
   * This method is called from the Analyzer.removeWorksheet method.
   *
   * @param query The query that is no longer used. 
   * 
   * @see Analyzer#removeWorksheet
   */
  public void removeDimensions(QueryClient query) {
      boolean listenerRemoved = false;
      
      try {
        QueryAccess queryAccess = query.createQueryAccess();
        Vector dimensions = queryAccess.getDimensions(LayerMetadataMap.LAYER_METADATA_NAME);

        for (int i = 0; i < dimensions.size() ; i++)  {
          // Find the index to the dimension in the list.
          int index = getDimensionIndex(dimensions.get(i).toString());

          // Decrement the counter
          DimensionInfo dimInfo = (DimensionInfo) m_dimensions.get(index);
          dimInfo.decrementUsageCount();
          
          // If there are no other dimensions, remove the dimension from the UI and the cache
          if (dimInfo.getUsageCount() == 0) {
            // Temporarily turn off the action listener in the dimension combo
            if (m_dimensionCombo.getListeners(ActionListener.class) != null) {
              m_dimensionCombo.removeActionListener(this);
              listenerRemoved = true;
            }
            
            m_dimensions.remove(index);
            m_dimensionCombo.removeItemAt(index);
          }
        }

        // If there are no dimension members left - reinitialize the UI
        if (m_dimensions.size() == 0) 
          setNotAvailable();
        // If there are dimensions left - and the action listener was removed, the add it back
        else if (listenerRemoved)
          m_dimensionCombo.addActionListener(this);
        
      }
      catch (Exception e) {
        System.out.println("Error removing dimensions to the dimension list.");
      }
      
  }
  /**
   * Adds dimensions to the list of dimensions in this Explorer, as necessary.  
   * This method updates the list of dimensions, adding any dimensions that
   * are in the specified query and not already in the list of dimensions.
   * If the specified query is the first query in the application, then this 
   * method also initializes this Explorer.
   * <p>
   * The Analyzer.addWorksheet method calls this method when a user opens
   * or creates a worksheet.
   * 
   * @param query  The query whose dimensions to add to this Explorer.
   * 
   * @see Analyzer#addWorksheet
   */
  public void addDimensions(QueryClient query) {
      // Make this the current query
      setQuery(query);
      
      // If the dimension is not in the dimension list, then add it.
      try {
        QueryAccess queryAccess = getQuery().createQueryAccess();
        Vector dimensions = queryAccess.getDimensions(LayerMetadataMap.LAYER_METADATA_NAME);

        for (int i = 0; i < dimensions.size() ; i++)  {
          MDDimension mdDimension = getMetadataManager().getDimensionByUniqueID(dimensions.get(i).toString());

          // If the dimension is not currently in the cache, add it
          if (!inDimensionList(mdDimension.getUniqueID())) {
            // Create a new dimensionInfo object
            DimensionInfo dimInfo = new DimensionInfo(mdDimension.getName(), 
                                                      mdDimension.getUniqueID(),
                                                      mdDimension.getShortLabel(),
                                                      queryAccess.getSelection(mdDimension.getUniqueID()).getHierarchy());

            // Increment the usage count of the dimension
            dimInfo.incrementUsageCount();

            // Add the dimension info object to the list of dimensions used by the Explorer
            m_dimensions.add(dimInfo);

            // Add the dimension to the dimension list combo
            m_dimensionCombo.addItem(mdDimension.getShortLabel());
          }
          // If the dimension is currently in the cache, increment its usage count
          else {
            int j = getDimensionIndex(mdDimension.getUniqueID());
            ((DimensionInfo) m_dimensions.get(j)).incrementUsageCount();
          }

          // Update the explorer UI if nec.
          if (!isExplorerVisible) {
            initializeExplorer();
          }
        }
      }
      catch (Exception e) {
        System.out.println("Error adding dimensions to the dimension list.");
      }
  }

  /**
   * Responds to user clicks in this Explorer.
   * This method responds when a user selects a different dimension and
   * when a user clicks the Go button.
   * 
   * @param e Information about the user action.
   * 
   * @see #updateExplorer
   * @see #applyDimListSelection
   */
  // This event is called when the user picks a dimension from the combo box
  public void actionPerformed(ActionEvent e) {
    if (e.getSource() == m_dimensionCombo)
      updateExplorer();
    else
      applyDimListSelection();
  }

  /**
   * Responds to dragging.
   * 
   * @param dge Information about the drag gesture.
   */
  public void dragGestureRecognized(DragGestureEvent dge) {
     // drag anything ...
     dge.startDrag(DragSource.DefaultCopyDrop, 
        new StringSelection("MEMBER:"), // transferable
        this); // drag source listener
      
  }

  /**
   * Null implementation for DragSourceListener.
   */
  public void dragEnter(DragSourceDragEvent dsde) {}
  /**
   * Null implementation for DragSourceListener.
   */
  public void dragOver(DragSourceDragEvent dsde) {}
  /**
   * Null implementation for DragSourceListener.
   */
  public void dropActionChanged(DragSourceDragEvent dsde) {}
  /**
   * Null implementation for DragSourceListener.
   */
  public void dragExit(DragSourceEvent dse) {}
  /**
   * Null implementation for DragSourceListener.
   */
  public void dragDropEnd(DragSourceDropEvent dsde) {} 

  /**
   * Information about a dimension.  
   * This class stores the name, short label, hierarchy, and unique ID of the
   * dimension.
   * It also tracks the number of queries that are accessing the dimension.
   */
  private class DimensionInfo {
    /**
     * The dimension name.
     */
    private String m_name;
    /**
     * The short label for the dimension.
     * This is displayed in the dimension combo box.
     */
    private String m_shortLabel;
    /**
     * The hierarchy that the dimension uses for the active query.
     */
    private String m_hierarchy;
    /**
     * The unique ID.
     */
    private String m_uniqueID;
    /**
     * Number of queries that use the dimension.
     * @see DimensionExplorer#addDimensions
     * @see DimensionExplorer#removeDimensions
     */
    private int m_usageCount = 0;

    /**
     * Constructor.
     * 
     * @param name The dimension name.
     * @param uniqueID The unique ID.
     * @param shortLabel The short label.
     * @param hierarchy The current hierarchy.
     * 
     * @see DimensionExplorer#addDimensions
     */
    public DimensionInfo (String name, String uniqueID, String shortLabel, 
                          String hierarchy) {
      m_name = name;
      m_uniqueID = uniqueID;
      m_shortLabel = shortLabel;
      m_hierarchy = hierarchy;
    }

    /**
     * Increments the usage count.
     * This method is called from the addDimensions method of the outer class,
     * after a user creates or opens a worksheet.
     * 
     * @see DimensionExplorer#addDimensions
     */
    public void incrementUsageCount () {
      m_usageCount++;
    }

    /**
     * Decrements the usage count.
     * This method is called from the removeDimensions method of the outer class,
     * after a user closes a worksheet.
     * 
     * @see DimensionExplorer#removeDimensions
     */
    public void decrementUsageCount() {
      m_usageCount = m_usageCount - 1;
    }

    /**
     * Returns the number of queries that are referring to the dimension.
     * 
     * @return The usage count for this DimensionInfo.
     */
    public int getUsageCount() {
      return m_usageCount;
    }

    /*
     * Get the attributes for the dimension
     */
    /**
     * Gets the name of the dimension.
     * 
     * @return The dimension name.
     */
    public String getName () {
       return m_name;
    }

    /**
     * Gets the short label of the dimension.
     * 
     * @return The dimension short label.
     */
    public String getShortLabel () {
       return m_shortLabel;
    }

    /**
     * Gets the hierarchy that the dimension uses for the active query.
     * 
     * @return The hierarchy for the dimension for the active query.
     */
    public String getHierarchy () {
       return m_hierarchy;
    }

    /**
     * Gets the unique ID for the dimension.
     * 
     * @return The unique ID.
     */
    public String getUniqueID () {
       return m_uniqueID;
    }
  }
}