Package com.ca.directory.jxplorer.search

Source Code of com.ca.directory.jxplorer.search.SearchGUI

package com.ca.directory.jxplorer.search;

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.logging.Logger;

import javax.swing.ImageIcon;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.TitledBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import com.ca.commons.cbutil.CBBasicComboBoxRenderer;
import com.ca.commons.cbutil.CBButton;
import com.ca.commons.cbutil.CBDialog;
import com.ca.commons.cbutil.CBIntText;
import com.ca.commons.cbutil.CBJComboBox;
import com.ca.commons.cbutil.CBListSelector;
import com.ca.commons.cbutil.CBPanel;
import com.ca.commons.cbutil.CBUtility;
import com.ca.commons.cbutil.Theme;
import com.ca.commons.naming.DN;
import com.ca.directory.jxplorer.HelpIDs;
import com.ca.directory.jxplorer.JXplorer;

/**
*  This class creates a dialog that has currently three tabs on it.  The first one is for
*  creating or building filters, the second on is for joining already created filters and the third
*   one allows the user to enter or paste in a text filter. This class acts as a
*  a controller between the view (build, join & text tabs) and the model (SearchModel) as well as being a part of
*  the view itself.
<p>
*  This class, in brief, sets up a search dialog that can be used to build, load, view, edit, join or save filters aswell
*  as search an LDAP directory with the filter that the user has created.
@author Trudi.
*/
public class SearchGUI extends CBDialog
{
  final JXplorer        jx;
    protected JTabbedPane    tabbedPane; 
  JCheckBox          aliasSearchCheckBox, aliasFindingCheckBox;
  JTextField          baseDNTextField, filterNameTextField;
  CBJComboBox          andOrCombo, searchLevelCombo, returnAttributesCombo;
  static final String[]    andOrArray = new String[] {CBIntText.get("And"), CBIntText.get("Or")};
  static final String[]    searchLevelArray = new String[] {CBIntText.get("Search Base Object"), CBIntText.get("Search Next Level"), CBIntText.get("Search Full Subtree"),};
  static final int       BASEOBJECTSEARCH=0, ONELEVELSEARCH=1, FULLSUBTREESEARCH=2
  CBButton           btnSave, btnLoad, btnMore, btnLess, btnView;
  BuildFilterPanel      build;
  JoinFilterPanel        join;
  TextFilterPanel        text;
  SearchModel          searchModel;
  String            buildName = "Untitled", joinName = "Untitled", textName = "Untitled";
  CBButton[]          btnEdit = new CBButton[50];
  int              buttonCounter = 0;        //TE: a counter that keeps track of the number of created 'edit' buttons and is used when recalling buttons from the button array..
  String[]          returnAttrs = null;

    private static Logger log = Logger.getLogger(SearchGUI.class.getName());

  //private static ReturnAttributesDisplay rat = null;

   /**
    *  Contructor that sets up the display and initiates the main search objects: SearchModel,
  *  BuildFilterPanel, JoinFilterPanel and TextFilterPanel.
  *  @param  baseDN the DN of the currently selected entry (i.e. unless changed is where the search will be conducted from).
  *  @param jxplorer JXplorer.
  */
  public SearchGUI(DN baseDN, JXplorer jxplorer)
  {
    super(jxplorer, CBIntText.get("Search"), HelpIDs.SEARCH);   
    jx = jxplorer;

    build = new  BuildFilterPanel(jx);
    join = new JoinFilterPanel(getEditButton());
    text = new TextFilterPanel();
   
    buttonCounter++;
    searchModel = new SearchModel();
   
    CBPanel panel = getMainPanel(baseDN);
   
    tabbedPane = new JTabbedPane();

    tabbedPane.addTab(CBIntText.get("Build Filter"), new ImageIcon(Theme.getInstance().getDirImages()+"build.gif"), build, CBIntText.get("Build a filter from scratch."));
    tabbedPane.addTab(CBIntText.get("Join Filters"), new ImageIcon(Theme.getInstance().getDirImages()+"join.gif"), join, CBIntText.get("Join filters that have been made in the Build tab."));
    tabbedPane.addTab(CBIntText.get("Text Filter"), new ImageIcon(Theme.getInstance().getDirImages()+"text.gif"), text, CBIntText.get("Type or paste a filter into the field in plain text."));
   
    OK.setText(CBIntText.get("Search"));
   
    display.makeHeavy();
    display.addln(panel);   
    display.add(tabbedPane);
    display.makeLight();
    display.add(getButtonPanel());

    CBButton btnAttrs = new CBButton(CBIntText.get("Return Attrs"), CBIntText.get("Select Returning Attributes."));
    btnAttrs.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e){
          ArrayList list = CBListSelector.getSelectedValues(jx, build.getAttributes(), CBIntText.get("Select Returning Attributes"), HelpIDs.SEARCH);
          if(list!=null)
            returnAttrs = (String[])list.toArray(new String[list.size()]);
    }});   
       
    setSize(550, 400);
    CBUtility.center(this, jx);
   
        /**
         *  This change listener is intended to listen for tab changes.
     *  Updates the filter name as the user flicks between tabs &
     *  enables or disables the controller buttons depending on which
     *  tab is visible.
         */
        tabbedPane.addChangeListener(new ChangeListener()
        {
            public void stateChanged(ChangeEvent e)
            {
                int index = tabbedPane.getSelectedIndex();
               
                if (index == 0)
        {
          filterNameTextField.setText(buildName);
          setButtons(true);
        }
                else if (index == 1)
        {
                    filterNameTextField.setText(joinName);
          setButtons(true);
        }
        else if (index ==2)
        {
          filterNameTextField.setText(textName);
          setButtons(false);
        }   
            }
        });     
 

   /**
    *  Sets up a panel with the components which display the name of the filter, the base DN,
  *  aliase prefs, search level prefs and the button panel.
  *  @param baseDN the Distinguished Name where the searching is done from.  This is added to a text field on this panel.
  *  @return the panel with the components added.
  */
  public CBPanel getMainPanel(DN baseDN)
  {
    CBPanel panel = new CBPanel();
   
    //TE: adds a label & text field for the name of the filter...
    panel.add(new JLabel(CBIntText.get("Filter Name") + ": "));
    panel.makeWide();
    panel.add(filterNameTextField = new JTextField("Untitled"));
    panel.makeLight();
    panel.newLine();   

    //TE: adds a label & text field for the name of the DN being searched from...
    panel.add(new JLabel(CBIntText.get("Start Searching From") + ": "));
    panel.makeWide();
    if(baseDN == null)
      panel.add(baseDNTextField = new JTextField(""));
    else
       panel.add(baseDNTextField = new JTextField(baseDN.toString()))
    panel.makeLight();
    panel.newLine();
   
    CBPanel optionsPanel = new CBPanel()//TE: panel for adding the alias & search level panels to (for layout).

    //TE: alias check boxes... 
    CBPanel aliasPanel = new CBPanel();
         aliasPanel.setBorder(new TitledBorder(CBIntText.get("Alias Options")));
   
    aliasPanel.makeWide();
    aliasPanel.addln(aliasSearchCheckBox = new JCheckBox(CBIntText.get("Resolve aliases while searching.")));   
    aliasSearchCheckBox.setToolTipText(CBIntText.get("Resolve aliases while searching."));
    aliasPanel.addln(aliasFindingCheckBox = new JCheckBox(CBIntText.get("Resolve aliases when finding base object.")))
    aliasFindingCheckBox.setToolTipText(CBIntText.get("Resolve aliases when finding base object."));

    //TE: search level combo...
    CBPanel searchLevelPanel = new CBPanel();
    searchLevelPanel.setBorder(new TitledBorder(CBIntText.get("Search Level")))
    searchLevelPanel.addln(new JLabel(CBIntText.get("Select Search Level") + ": "));
    searchLevelPanel.makeWide();
    searchLevelPanel.addln(searchLevelCombo = new CBJComboBox(searchLevelArray));
    searchLevelCombo.setSelectedIndex(FULLSUBTREESEARCH)
   
    //TE: put the alias & search level panels on the options panel then add the options panel to the main panel...
    optionsPanel.add(aliasPanel);
    optionsPanel.makeWide();
    optionsPanel.addln(searchLevelPanel);
   
    panel.makeWide();
    panel.addln(optionsPanel);
 
    //TE: return attributes combo...   
    CBPanel returnAttrsPanel = new CBPanel();
    returnAttributesCombo = new CBJComboBox(ReturnAttributesDialog.getSavedListNames())
    returnAttributesCombo.setSelectedItem(ReturnAttributesDialog.DEFAULT_RETURN_ATTRS);
 
    returnAttrsPanel.makeLight();
    returnAttrsPanel.add(new JLabel(CBIntText.get("Information to retrieve")+": "));
    returnAttrsPanel.makeWide();
    returnAttrsPanel.addln(returnAttributesCombo);
   
    panel.addln(returnAttrsPanel);
   
    return panel;   
  }

    /**
     * Sets the base DN in the base DN text field.
     * @param baseDN the DN to search from.
     */
    public void setBaseDN(DN baseDN)
    {
        if(baseDN != null)
            baseDNTextField.setText(baseDN.toString());
    }

   /**
    *  Returns a panel with four buttons on it: More, Less, Save & View.  The buttons are set up
  *  with listeners and are placed one above the other.
  *  @return the panel with the buttons on it.
  */
  public CBPanel getButtonPanel()
  {
    CBPanel panel = new CBPanel();   

    btnMore = new CBButton(CBIntText.get("More"), CBIntText.get("Add a Line to the search window."));
    btnMore.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e){
          if (isFilterValid()) 
          {
            if (tabbedPane.getSelectedIndex()==0//TE: make sure that you are adding rows to the tab that is visible, not to both tabs!
            {
              build.addFilterRow();
            }
            else if (tabbedPane.getSelectedIndex()==1 && buttonCounter<50)
            { 
              join.addFilterRow(getEditButton());  
              buttonCounter++;          //TE: a counter that keeps track of the number of created 'edit' buttons.        
            }
          }
          else
          {
            showMessage(CBIntText.get("There is an error in the filter; there appears to be missing information.\nPlease make sure you have entered all the information for the filter correctly,\nthen try to add more rows."), CBIntText.get("Missing Information"));             
          }
    }});
   
    btnLess = new CBButton(CBIntText.get("Less"), CBIntText.get("Remove a Line from the search window."));
    btnLess.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e){
          if (tabbedPane.getSelectedIndex()==0//TE: make sure that you are removing rows from the tab that is visible, not from both tabs!
          {
            build.removeFilterRow();
          }
          else if (tabbedPane.getSelectedIndex()==1 && buttonCounter>1)
          {    
            buttonCounter--; 
            join.removeFilterRow(btnEdit[buttonCounter]);                   
          }
    }})
   
    btnSave = new CBButton(CBIntText.get("Save"), CBIntText.get("Save this filter."));
    btnSave.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e){
          if (isFilterValid())
            save();
          else
            showMessage(CBIntText.get("The filter cannot be constructed; there appears to be missing information.\nPlease make sure you have entered all the information for the filter correctly."), CBIntText.get("Missing Information"));             
    }});
   
    btnLoad = new CBButton(CBIntText.get("Load"), CBIntText.get("Load a previously saved filter."));
    btnLoad.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e){
          if(tabbedPane.getSelectedIndex()==0)
            loadBuild();
          else if(tabbedPane.getSelectedIndex()==1)
            loadJoin()
          else if(tabbedPane.getSelectedIndex()==2)
            loadText();             
    }});   
   
    btnView = new CBButton(CBIntText.get("View"), CBIntText.get("View this search filter as text."));
    btnView.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e){
          if (!isFilterValid())
            showMessage(CBIntText.get("The filter cannot be constructed; there appears to be missing information.\nPlease make sure you have entered all the information for the filter correctly."), CBIntText.get("Missing Information"));
          else if(tabbedPane.getSelectedIndex()==1 && recursiveFilterCheck(null, join.getFilter(), "View"))   // We don't care about the name of this filter b/c we are just viewing it.
            return
          else
            showDialog(CBIntText.get("Current Filter"), getLDAPFilter());
    }});

    panel.makeHigh();        //TE: add a label that it takes up the any remaining space above the buttons, so that the buttons are at the bottom of the panel.
    panel.addln(new JLabel(" "));
    panel.makeLight();
    panel.addln(btnMore);
    panel.addln(btnLess);
    panel.addln(btnSave);
    panel.addln(btnLoad);
    panel.addln(btnView)
   
    return panel;
  }

   /**
  *  Enables or disables the More, Less and View buttons.  We basically don't
  *  want these buttons enabled if the user has selected the Text Filter tab.
  *  @param state the state of the buttons (enabled=true or disabled=false).
  */
  protected void setButtons(boolean state)
  {
    btnMore.setEnabled(state);
    btnLess.setEnabled(state);
    btnView.setEnabled(state)
  }

   /**
    *  Displays a JOptionPane message with a text area containing the current filter. 
  *  The text area is set to do line wrapping and only vertical scrolling.
  *  @param title the heading of the dialog that appears in the title bar.
  *  @param filter the current LDAP filter (or any string to be displayed).
  */
  protected void showDialog(String title, String filter)
  {
    JTextArea area = new JTextArea(filter);
    area.setLineWrap(true);    
    area.setWrapStyleWord(true);
    JScrollPane scrollPane = new JScrollPane(area);
        scrollPane.setPreferredSize(new Dimension(300,60));
    scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        JOptionPane.showMessageDialog(this, scrollPane, title, JOptionPane.INFORMATION_MESSAGE);
  }   

   /** 
    *  Returns an edit button, i.e. a button labelled "Edit", has a dimension of 55x21, has a tooltip "Edit
  *  this filter.", and has an action listener that calls the edit method with it's position (or row number).
  *  @return the configured button.
  */
  protected CBButton getEditButton()
  {
    btnEdit[buttonCounter] = new CBButton(CBIntText.get("Edit"), CBIntText.get("Edit this filter."));

    btnEdit[buttonCounter].setPreferredSize(new Dimension(55,21));
    btnEdit[buttonCounter].addActionListener(new ActionListener()
    {
      public void actionPerformed(ActionEvent e)
      {
        CBButton item = (CBButton)e.getSource();

        for(int i=0; i<buttonCounter; i++)
        {
          if (item == btnEdit[i])
              edit(i);
        }
      }
    });
   
    return btnEdit[buttonCounter];
  }
 
   /**
    *  Displays the filter(s) corresponding to the edit button that the user has selected.
  *  The edit buttons live on the join panel.  If a user wants to edit a raw filter the raw filter
  *  is displayed in the build panel otherwise if the user wants to edit a filter that is a combination
  *  of filters, the filter is displayed in the join panel.
  *  @param row the row number that the filter name is to be taken from.
  */
  protected void edit(int row)
  {
    ArrayList list = searchModel.getFilterNames(SearchModel.BUILDFILTER);            //TE: get all the raw filter names.
    String filter = join.getFilterComboValue(row);
   
    if (filter==null)                          //TE: will equal null if nothing to edit.     
    {   
      showMessage(CBIntText.get("There are no filters available to edit"), CBIntText.get("Nothing to Edit"));
      return;
    }
    else
    {   
      try     
      {
        if (list.contains(filter))                  //TE: the filter is a raw filter which needs to be displayed in the build filter panel.
        {
          buildName = filter;                    //TE: set the global variable so that the correct name of the filter is displayed when tabs are changed.
          tabbedPane.setSelectedIndex(0);              //TE: change tabs.

          build.displayFilter(searchModel.getFilter(filter));    //TE: send the raw filter off to get displayed.
        }
        else                            //TE: the filter is a combination of filters which need to be displayed in the join filter panel.
        {
          String value = searchModel.getFilter(filter);      //TE: get the value of the filter.

          setNumberOfRows(build.getOccurrences(searchModel.getFilter(filter), "JXFilter"));    //TE: ...set up that many number of rows.
         
          ArrayList aList = searchModel.getJoinFilterNames(value);                //TE: get the names of these filters.
         
          if (!join.displayFilter(aList, value))
          {
            showMessage(CBIntText.get("Your filter cannot be edited."), CBIntText.get("Edit Unsuccessful"));
          }
          else
          {
            joinName = filter; 
            filterNameTextField.setText(joinName);         //TE: set the global variable so that the correct name of the filter is displayed.             
          }           
        }
      }
      catch(Exception e)                //TE: the user has somehow selected nothing in either the attribute or the function combo.
      {
        showMessage(CBIntText.get("The filter cannot be constructed; there appears to be missing information.\nPlease make sure you have entered all the information for the filter correctly."), CBIntText.get("Missing Information"));     
        return;
      }
    }
  }
   
   /**
    *  Currently used by the loadJoin() and edit() methods to prompt the JoinFilterPanel class to either add or remove
  *  rows.  If adding rows is required, the extra number of edit buttons are created before the hand-balling goes off
  *  to the JoinFilterPanel class.
  *  @param rows the number of rows that need to be added.
  */
  protected void setNumberOfRows(int rows)
  {
    if (buttonCounter > rows)          //TE: if there are more buttons than rows required...
    {
      while (buttonCounter > rows)      //TE: ...delete these buttons and any other components on that row until the correct number of rows are displayed.
      {   
        buttonCounter--;          //TE: make sure the button counter is updated.
        join.removeFilterRow(btnEdit[buttonCounter]);   
      }
    }
    else if (buttonCounter < rows)        //TE: if there are less buttons than rows required...
    {
      while (buttonCounter < rows)      //TE: ...create and add these buttons and any other required components on that row until the correct number of rows are displayed.
      {   
        join.addFilterRow(getEditButton());  
        buttonCounter++;           //TE: make sure the button counter is updated.
      }
    }
  }

   /**
    *  Save the filter to the property file 'search_filter.txt".  Checks first to see if the filter exists.  If
  *  it does a JOptionPane message asks the user if they want to replace it.  If the filter is saved successfully
  *  a confirmation message is displayed again using JOptionPane.  This also updates the filter combo of the join
  *  tab so that a user can see changes straight away. 
  */
  protected void save()
  {
    String name = filterNameTextField.getText()//TE: get the user defined name for the filter.
    boolean exists = false;              //TE: true if the name exists, false otherwise.
   
    if (name == null || name.trim().length()<=0 || name.equalsIgnoreCase("Untitled"))
    {   
      showMessage(CBIntText.get("Please enter a name in the 'Filter Name' field for the filter that you are trying to save."), CBIntText.get("Name Required"));     
      return;
   
    else if (name.startsWith("JXFilter"))
    {
      showMessage(CBIntText.get("The name ''{0}'' is a reserved name.  Please enter a different name.", new String[] {name}), CBIntText.get("Naming Error"));
      return;
    }
   
    if (searchModel.exists(name))          //TE: if the name exists ask the user if they want to replace it...
    {
      int response = JOptionPane.showConfirmDialog(this, CBIntText.get("The name ''{0}'' already exists.  Do you want to replace it?", new String[] { name }),
            CBIntText.get("Select Filter"), JOptionPane.YES_NO_OPTION );

      if(response != JOptionPane.YES_OPTION)
        return;   
     
      exists = true
    }     
   
    try
    {
      if (tabbedPane.getSelectedIndex()==0)
      {
        buildName = name;             //TE: update the name of the build filter so the tab change listener knows the correct name of the filter.         
        searchModel.saveFilter(name, getLDAPFilter())
      }
      else if (tabbedPane.getSelectedIndex()==1)
      { 
        String filter = join.getFilter();       
       
        if(recursiveFilterCheck(name, filter, "Save"))  //TE: stop the user from constructing a filter that is recursive.
          return;
                 
        joinName = name;            //TE: update the name of the join filter so the tab change listener knows the correct name of the filter.
        searchModel.saveFilter(name, filter)
      }
      else if (tabbedPane.getSelectedIndex()==2)
      {
        textName = name;            //TE: update the name of the text filter so the tab change listener knows the correct name of the filter.         
        searchModel.saveTextFilter(name, text.getFilter());
      }
    }
    catch(Exception e)                //TE: the user has somehow selected nothing in either the attribute or the function combo.
    {
      showMessage(CBIntText.get("The filter cannot be constructed; there appears to be missing information.\nPlease make sure you have entered all the information for the filter correctly."), CBIntText.get("Missing Information"));     
      return;
    }   
     
    save(name);                    //TE: save search levels, baseDN etc.
     
    if(!exists)                    //TE: update the filter combo if the filter doesn't exist.  Otherwise you would need to close the search dialog to see any changes??
      join.updateFilterCombo(name);
   
    jx.getMainMenu().updateSearchMenu();      //TE: updates the Search menu items.     
   
    showMessage(CBIntText.get("Your filter ''{0}'' was saved successfully.", new String[] {name}), CBIntText.get("Successful Save."));
  }

   /**
    *  Saves the base DN, return attribute list name, the search level and the alias
  *  state to the property file so they can be loaded similar to the filter.
  *  @param name the name of the filter, will be used in the key (e.g. name.baseDN=whatever).
  */
  protected void save(String name)
  {
    String baseDN = ((baseDNTextField.getText()).trim()).length()<=0 ? ((jx.getTree()).getRootDN()).toString() : baseDNTextField.getText();
    searchModel.saveValue(name, SearchModel.BASEDN, baseDN);
    searchModel.saveValue(name, SearchModel.RETATTRS, (returnAttributesCombo.getSelectedItem()).toString());
    searchModel.saveSearchLevel(name, searchLevelCombo.getSelectedIndex());
    searchModel.saveAlias(name, SearchModel.FIND, aliasFindingCheckBox.isSelected());
    searchModel.saveAlias(name, SearchModel.SEARCH, aliasSearchCheckBox.isSelected());
  }

   /**
    *  Displays a JOptionPane message which has a combo box containing all the possible filters that can be
  *  loaded into the build display.  Gets the user selection and hand-balls the loading off to the BuildFilterPanel class. 
  */
  protected void loadBuild()
  {
    ArrayList list = searchModel.getFilterNames(SearchModel.BUILDFILTER)//TE: get the names of raw filters (i.e. (cn=f*)).
   
    if (list.size()==0)
    {
      showMessage(CBIntText.get("There are no filters available to load.") , CBIntText.get("Nothing to Load"));
      return;
    }   
   
    Object listOb[] = list.toArray();
    Arrays.sort(listOb, new SearchModel.StringComparator());        //TE: sort the list alphabetically.
   
    CBJComboBox loadCombo = new CBJComboBox(listOb);
    loadCombo.setRenderer(new CBBasicComboBoxRenderer(listOb));
    loadCombo.setPreferredSize(new Dimension(140, 20));
        int response = JOptionPane.showConfirmDialog(this, loadCombo, CBIntText.get("Select Filter"), JOptionPane.OK_CANCEL_OPTION);
           
        if (response != JOptionPane.OK_OPTION)
            return;                                  //TE: the user has probably decided not to load a filter i.e. has clicked 'cancel'.
       
    if (loadCombo.getSelectedItem()!=null)
    {
      String filter=null;
      try
      {
            filter = searchModel.getFilter(loadCombo.getSelectedItem().toString())//TE: gets the filter that the user selected. 
      }
      catch(Exception e)                //TE: the user has somehow selected nothing in either the attribute or the function combo.
      {
        showMessage(CBIntText.get("The filter cannot be constructed; there appears to be missing information.\nPlease make sure you have entered all the information for the filter correctly."), CBIntText.get("Missing Information"));     
        return;
      }       
     
      if (!build.displayFilter(filter))                  //TE: display the filter.  If unsuccessful show message.
      {
        showMessage(CBIntText.get("Your filter cannot be displayed."), CBIntText.get("Load Unsuccessful"))
      }
      else
      {   
        buildName = loadCombo.getSelectedItem().toString();        //TE: update the name of the join filter so the tab change listener knows the correct name of the filter.
        filterNameTextField.setText(buildName);              //TE: set the name of the filter in the filter name field.
      }
    }
    else
      showMessage(CBIntText.get("Problem loading; there are no filters selected.") , CBIntText.get("Nothing to Load"))
   
    load(loadCombo.getSelectedItem().toString())
  }
 
   /**
    *  Displays a JOptionPane message which has a combo box containing all the possible filters that can be
  *  loaded into the join display.  Gets the user selection and creates the edit buttons before hand-balling
  *  the loading off to the JoinFilterPanel class. 
  */
  protected void loadJoin()
  {
    ArrayList list = searchModel.getFilterNames(SearchModel.JOINFILTER)//TE: get the names of filters that are made up of other filters (i.e. not raw filters).

    if (list.size()==0)
    {
      showMessage(CBIntText.get("There are no filters available to load.") , CBIntText.get("Nothing to Load"));
      return;
    }
   
    CBJComboBox loadCombo = new CBJComboBox(list.toArray());
    loadCombo.setRenderer(new CBBasicComboBoxRenderer(list.toArray()));
    loadCombo.setPreferredSize(new Dimension(140, 20));
        int response = JOptionPane.showConfirmDialog(this, loadCombo,
                                    CBIntText.get("Select Filter"), JOptionPane.OK_CANCEL_OPTION);
           
        if (response != JOptionPane.OK_OPTION)
            return;                                  //TE: the user has probably decided not to load a filter i.e. has clicked 'cancel'.
       
    if (loadCombo.getSelectedItem()!=null)
    {   
      String filter = loadCombo.getSelectedItem().toString();        //TE: get the user selected filter from the combo box.
     
      try
      {
        setNumberOfRows(build.getOccurrences(searchModel.getFilter(filter), "JXFilter"))//TE: add the right number of rows for displaying the filter.
       
            list = searchModel.getJoinFilterNames(searchModel.getFilter(filter));        //TE: get a list of the subfilter names.
       
        if(!join.displayFilter(list, searchModel.getFilter(filter)))  //TE: display the filter.  If unsuccessful show message.
          showMessage(CBIntText.get("Your filter cannot be displayed."), CBIntText.get("Load Unsuccessful"));   
        else
        {   
          joinName = loadCombo.getSelectedItem().toString();      //TE: update the name of the join filter so the tab change listener knows the correct name of the filter.
          filterNameTextField.setText(joinName);            //TE: set the name of the filter in the filter name field.
        }
      }
      catch(Exception e)                //TE: the user has somehow selected nothing in either the attribute or the function combo.
      {
        showMessage(CBIntText.get("The filter cannot be constructed; there appears to be missing information.\nPlease make sure you have entered all the information for the filter correctly."), CBIntText.get("Missing Information"));     
        return;
      }
    }
    else
      showMessage(CBIntText.get("Problem loading; there are no filters selected.") , CBIntText.get("Nothing to Load"))
   
    load(loadCombo.getSelectedItem().toString())
  }

   /**
    *  Displays a JOptionPane message which has a combo box containing all the possible filters
  *  that can be loaded into the text display.  Gets the user selection and hand-balls
  *  the loading off to the JoinFilterPanel class. 
  */
  //TE: Perhaps allow the user to load any filter into the text area, not just text filters???
  protected void loadText()
  {
    ArrayList list = searchModel.getFilterNames(SearchModel.TEXTFILTER)//TE: get the names of filters that are made up of other filters (i.e. not raw filters).

    if (list.size()==0)
    {
      showMessage(CBIntText.get("There are no filters available to load.") , CBIntText.get("Nothing to Load"));
      return;
   
   
    CBJComboBox loadCombo = new CBJComboBox(list.toArray());
    loadCombo.setRenderer(new CBBasicComboBoxRenderer(list.toArray()));
    loadCombo.setPreferredSize(new Dimension(140, 20));
        int response = JOptionPane.showConfirmDialog(this, loadCombo, CBIntText.get("Select Filter"), JOptionPane.OK_CANCEL_OPTION);
           
        if (response != JOptionPane.OK_OPTION)
            return
     
    if (loadCombo.getSelectedItem()!=null)
    {   
      textName = loadCombo.getSelectedItem().toString();          //TE: get the user selected filter from the combo box.       
      text.displayFilter(searchModel.getTextFilter(textName));
      filterNameTextField.setText(textName);                //TE: set the name of the filter in the filter name field.
    }
    else
      showMessage(CBIntText.get("Problem loading; there are no filters selected.") , CBIntText.get("Nothing to Load"));             
   
    load(loadCombo.getSelectedItem().toString())
  }
 
   /**
    *  Gets the values of the base dn, search level, return attributes and alias state from the
  *  property file that pertain to the filter being loaded and sets these values in
  *  the GUI.
  *  @param name the name of the filter that is being loaded.
  */
  protected void load(String name)
  {
    //TE: load search level...
    int searchLevel = 2;
    try
    {
      searchLevel = Integer.parseInt(searchModel.getValue(name + "." + SearchModel.SEARCHLEVEL));
      searchLevelCombo.setSelectedIndex(searchLevel);
    }
    catch(NumberFormatException  e)
    {
      searchLevelCombo.setSelectedIndex(2);
    }   
       
   
    //TE: load base dn...
    String dn = searchModel.getValue(name + "." + SearchModel.BASEDN);
    if(dn!=null)
      baseDNTextField.setText(dn);

    //TE: get the name of the return attribute list.  Check that the list name exists then
    //    set it in the combo... 
    String retAttrs = searchModel.getValue(name + "." + SearchModel.RETATTRS);
    if (retAttrs!=null)
    {
      Object temp[] = ReturnAttributesDialog.getSavedListNames();
     
      for(int i=0; i<temp.length;i++)
      {
        if (((String)temp[i]).equalsIgnoreCase(retAttrs))
        {
          returnAttributesCombo.setSelectedItem(temp[i]);
          break;
        }
      }
    }

    //TE: select finding alias checkboxes...
    String find = searchModel.getValue(name + "." + SearchModel.FIND);
    if (find!=null)
    {     
      if(find.equalsIgnoreCase("true"))
        aliasFindingCheckBox.setSelected(true);
      else
        aliasFindingCheckBox.setSelected(false);
    }     
   
    //TE: select searching alias checkboxes...
    String search = searchModel.getValue(name + "." + SearchModel.SEARCH);
    if (search!=null)
    {
      if(search.equalsIgnoreCase("true"))
        aliasSearchCheckBox.setSelected(true);
      else
        aliasSearchCheckBox.setSelected(false);
   
  }
 
   /**
    *  Does a check to see if the filter is valid i.e. it check if there is a value in
  *  each of the combo boxes. 
  *  @return false if one or more of the combo boxes does not contain a value, true otherwise.
  */
  protected boolean isFilterValid()
  {
    if (tabbedPane.getSelectedIndex()==0)
      return build.isFilterValid();
    else if (tabbedPane.getSelectedIndex()==1
      return join.isFilterValid();
    else if(tabbedPane.getSelectedIndex()==2)
      return text.isFilterValid()
     
    return false//TE: something weird with the tabbed panes.
  }

   /**
    *  Returns the LDAP filter of the currently displayed tabbed pane.  This assumes that the build tab is at
  *  position 0, the join tab is at position 1 and the text tab is at position 2.
  *  @return the LDAP filter for example (cn=f*)
  */
  protected String getLDAPFilter()
  {
    if (tabbedPane.getSelectedIndex()==0)     
      return build.getFilter();
    else if(tabbedPane.getSelectedIndex()==1)
      return searchModel.getJoinFilter(join.getFilter());
    else if(tabbedPane.getSelectedIndex()==2)
      return text.getFilter();   
     
    return ""
  }

   /**
    *  Displays a information message dialog with the text that is supplied and titles the dialog with the title supplied.
  *  @param message the text to be displayed.
  *  @param title the title of this information message dialog.
  */
  protected void showMessage(String message, String title)
  {
    JOptionPane.showMessageDialog(this, message, title, JOptionPane.INFORMATION_MESSAGE );     
 

   /**
    *  Sets the search Alias Behaviour in the property file, gets the filter and executes the search & display
  *  before closing the window.
  */
  public void doOK()
  {   
    if (isFilterValid())
    {
            // Check if the filter is safe to use (we don't care about the name to begin with b/c we aren't saving)...
      if(tabbedPane.getSelectedIndex()==1 && recursiveFilterCheck(null, join.getFilter(), "Search"))
        return;   
      setAliasOptions();
     
      String returnAttrs = (returnAttributesCombo.getSelectedItem()).toString();
      if (!returnAttrs.equalsIgnoreCase(ReturnAttributesDialog.DEFAULT_RETURN_ATTRS))
      {
        closeSearchGUI();
        String[] attrNames = ReturnAttributesDialog.getReturnAttributes(returnAttrs);
        searchModel.openRetAttrDisplay(jx, attrNames, (jx.getSearchTree()).getDataSource());                           
        SearchExecute.run(jx.getSearchTree(), new DN(baseDNTextField.getText()), getLDAPFilter(), attrNames, searchLevelCombo.getSelectedIndex(), jx.getSearchBroker())//TE: the search details.       
      }     
      else
      {
        closeSearchGUI();
        SearchExecute.run(jx.getSearchTree(), new DN(baseDNTextField.getText()), getLDAPFilter(),
                        new String[] {"objectClass"}, searchLevelCombo.getSelectedIndex(), jx.getSearchBroker())//TE: the search details.      SearchExecute.run(jx.getSearchTree(), new DN(baseDNTextField.getText()), getLDAPFilter(), attrNames, searchLevelCombo.getSelectedIndex(), jx.getSearchBroker());  //TE: the search details.
     
      jx.getTreeTabPane().setSelectedComponent(jx.getResultsPanel())
    }   
    else
    {
      showMessage(CBIntText.get("The filter cannot be constructed; there appears to be missing information.\nPlease make sure you have entered all the information for the filter correctly."), CBIntText.get("Missing Information"));             
    }   
  }

    /**
     * Over writes the parent method to call the closeSearchGUI method.
     */
    public void doCancel()
    {
        closeSearchGUI();
    }

    /**
     * Sets the filter name text to 'Untitled' then
     * sets the visibility of the dialog to false.
     */
    public void closeSearchGUI()
    {
        filterNameTextField.setText("Untitled");        //TE: bug 4896.
        setVisible(false);
    }

   /**
    *  Determines which search alias behaviour the user has selected in the search GUI.
  *  The combinations are:
  *  <p>
  <b>always</b> - both alias check boxes are checked.<br>
  <b>never</b> - neither alias check boxes are checked.<br>
  *   <b>finding</b> - only the 'Resolve aliases when finding base object' check box is checked.<br>
  <b>searching</b> - only the 'Resolve aliases while searching' check box is checked.
  *  </p>
  *  The search alias option is set in JXplorer's property file under 'option.ldap.searchAliasBehaviour'.
  */
  public void setAliasOptions()
  {
    String aliasOption = "always";
   
    if (!aliasSearchCheckBox.isSelected() && !aliasFindingCheckBox.isSelected())
      aliasOption = "never";
    else if (aliasSearchCheckBox.isSelected() && !aliasFindingCheckBox.isSelected())
      aliasOption = "searching";
    else if (!aliasSearchCheckBox.isSelected() && aliasFindingCheckBox.isSelected())
      aliasOption = "finding";
   
    log.fine("Setting search alias option to: ["+aliasOption+"]");
    JXplorer.setProperty("option.ldap.searchAliasBehaviour", aliasOption);
  }

   /**
    *  Checks if the user is trying to save a copy of the filter into itself, for example
  *  if a filter named t3 contains the filter t3 as part of a join.  This check applies only
  *  for the join tab.  Constructs an info dialog if the filter is recursive.
  *  @param filterName the user specified name for the filter that is currently being saved.
  *  @param filter the value of the filter for example 'JXFilter.t1JXFilter.t1'.
  *  @param type the source of the filter being constructed for example: view, save or search (used in the info dialog).
  *  @return true if the filter contains itself, false otherwise.
  */
  protected boolean recursiveFilterCheck(String filterName, String filter, String type)
  {   
    if(recursiveFilterCheck(filterName, filter))  //TE: stop the user from constructing a filter that is recursive.
    {
      showMessage(CBIntText.get("The filter you are trying to {0} is not valid.  You may be trying to construct a filter within itself which will cause an infinite loop.", new String[] {type.toLowerCase()}), CBIntText.get(type) + " " + CBIntText.get("Error"));
      return true;
    }       
    return false;
  }
 
   /**
    *  Checks if the user is trying to save a copy of the filter into itself, for example
  *  if a filter named t3 contains the filter t3 as part of a join.  This check applies only
  *  for the join tab.
  *  @param filterName the user specified name for the filter that is currently being saved.
  *  @param filter the value of the filter for example 'JXFilter.t1JXFilter.t1'.
  *  @return true if the filter contains itself, false otherwise.
  */
  protected boolean recursiveFilterCheck(String filterName, String filter)
    {
    boolean recursive = false;
    String temp;
    ArrayList list = searchModel.getJoinFilterNames(filter);

    for(int i=0;i<list.size();i++)
      {
        temp = list.get(i).toString();
       
      if(filterName != null && filterName.compareTo(temp) == 0)
        {
        recursive = true;
        break;
        }
     
        // Go down each level that check there is the same name in the filter to be saved and the children fiters...
        String value = searchModel.getFilter(temp);

            // check if it is joint filter or not...
            if(value != null && value.indexOf("JXFilter") != -1)
        recursive = recursiveFilterCheck(filterName, value);

        if(recursive)
        return true;
    }
         
    return recursive;    
    }
}


//TE:  ONE DAY..........

//  class TreeFilterPanel extends CBPanel
//  {
//    public TreeFilterPanel() 
//    { 
//      setBackground(new Color(235,255,255));
//    }   
//  }


  
TOP

Related Classes of com.ca.directory.jxplorer.search.SearchGUI

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.