View Javadoc

1   /*
2    *   Copyright 2004 The Apache Software Foundation
3    *
4    *   Licensed under the Apache License, Version 2.0 (the "License");
5    *   you may not use this file except in compliance with the License.
6    *   You may obtain a copy of the License at
7    *
8    *       http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *   Unless required by applicable law or agreed to in writing, software
11   *   distributed under the License is distributed on an "AS IS" BASIS,
12   *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *   See the License for the specific language governing permissions and
14   *   limitations under the License.
15   *
16   */
17  package org.apache.ldap.server.partition.impl.btree.gui;
18  
19  
20  import java.awt.BorderLayout;
21  import java.awt.Dimension;
22  import java.awt.Toolkit;
23  import java.awt.Window;
24  import java.awt.event.ActionEvent;
25  import java.awt.event.ActionListener;
26  import java.io.File;
27  import java.io.FileNotFoundException;
28  import java.io.FileReader;
29  import java.io.IOException;
30  import java.math.BigInteger;
31  import java.util.HashMap;
32  import java.util.Hashtable;
33  import java.util.Iterator;
34  import java.util.Stack;
35  
36  import javax.naming.NamingEnumeration;
37  import javax.naming.NamingException;
38  import javax.naming.directory.Attributes;
39  import javax.naming.directory.SearchControls;
40  import javax.swing.JFileChooser;
41  import javax.swing.JFrame;
42  import javax.swing.JLabel;
43  import javax.swing.JMenu;
44  import javax.swing.JMenuBar;
45  import javax.swing.JMenuItem;
46  import javax.swing.JOptionPane;
47  import javax.swing.JPanel;
48  import javax.swing.JScrollPane;
49  import javax.swing.JSeparator;
50  import javax.swing.JSplitPane;
51  import javax.swing.JTabbedPane;
52  import javax.swing.JTable;
53  import javax.swing.JTextArea;
54  import javax.swing.JTree;
55  import javax.swing.event.TreeSelectionEvent;
56  import javax.swing.event.TreeSelectionListener;
57  import javax.swing.table.DefaultTableModel;
58  import javax.swing.tree.DefaultTreeModel;
59  import javax.swing.tree.TreeModel;
60  import javax.swing.tree.TreeNode;
61  import javax.swing.tree.TreePath;
62  
63  import org.apache.ldap.common.filter.ExprNode;
64  import org.apache.ldap.common.filter.FilterParser;
65  import org.apache.ldap.common.filter.FilterParserImpl;
66  import org.apache.ldap.common.ldif.LdifIterator;
67  import org.apache.ldap.common.ldif.LdifParser;
68  import org.apache.ldap.common.ldif.LdifParserImpl;
69  import org.apache.ldap.common.message.DerefAliasesEnum;
70  import org.apache.ldap.common.message.LockableAttributesImpl;
71  import org.apache.ldap.common.name.LdapName;
72  import org.apache.ldap.common.util.StringTools;
73  import org.apache.ldap.server.partition.impl.btree.BTreeContextPartition;
74  import org.apache.ldap.server.partition.impl.btree.Index;
75  import org.apache.ldap.server.partition.impl.btree.IndexRecord;
76  import org.apache.ldap.server.partition.impl.btree.SearchEngine;
77  import org.slf4j.Logger;
78  import org.slf4j.LoggerFactory;
79  
80  
81  /***
82   * The frame for the database.
83   * 
84   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
85   * @version $Rev: 264732 $
86   */
87  public class MainFrame extends JFrame
88  {
89      private static final Logger log = LoggerFactory.getLogger(MainFrame.class);
90  
91      private static final long serialVersionUID = 4049353102291513657L;
92  
93      // Swing Stuff
94      private JLabel statusBar = new JLabel( "Ready" );
95      private JPanel mainPnl = new JPanel();
96      private JSplitPane splitPane = new JSplitPane();
97      private JTabbedPane tabbedPane = new JTabbedPane();
98      private JPanel entryPnl = new JPanel();
99      private JPanel idxPnl = new JPanel();
100     private JScrollPane treePane = new JScrollPane();
101     private JTree tree = new JTree();
102     private JScrollPane entryPane = new JScrollPane();
103     private JTable entryTbl = new JTable();
104     private JScrollPane idxPane = new JScrollPane();
105     private JTable idxTbl = new JTable();
106     private JMenu searchMenu = new JMenu();
107     private JMenuItem annotate = new JMenuItem();
108     private JMenuItem run = new JMenuItem();
109     private JMenuItem debug = new JMenuItem();
110     private JMenu indices = new JMenu();
111 
112     // Non Swing Stuff
113     private BTreeContextPartition partition = null;
114     private boolean doCleanUp = false;
115     private HashMap nodes = new HashMap();
116     private EntryNode root = null;
117     private SearchEngine eng = null;
118 
119 
120     /***
121      * Creates new form JFrame
122      */
123     public MainFrame( BTreeContextPartition db, SearchEngine eng )
124         throws NamingException
125     {
126         partition = db;
127         this.eng = eng;
128 
129         initGUI();
130         buildIndicesMenu( partition );
131         pack();
132         load();
133     }
134 
135 
136     /***
137      * This method is called from within the constructor to initialize the form
138      */
139     private void initGUI() 
140     {
141         mainPnl.setBorder( null );
142         mainPnl.setLayout( new java.awt.BorderLayout() );
143         mainPnl.add( splitPane, java.awt.BorderLayout.CENTER );
144         splitPane.add( tabbedPane, javax.swing.JSplitPane.RIGHT );
145         splitPane.add( treePane, javax.swing.JSplitPane.LEFT );
146         tabbedPane.add( entryPnl, "Entry Attributes" );
147         tabbedPane.add( idxPnl, "Entry Indices" );
148 
149         entryPnl.setLayout( new java.awt.BorderLayout() );
150         entryPnl.add( entryPane, java.awt.BorderLayout.CENTER );
151 
152         idxPnl.setLayout( new java.awt.BorderLayout() );
153         idxPnl.add( idxPane, java.awt.BorderLayout.CENTER );
154 
155         getContentPane().setLayout( new java.awt.BorderLayout() );
156         JPanel content = new JPanel();
157         content.setPreferredSize( new java.awt.Dimension( 798, 461 ) );
158         content.setLayout( new java.awt.BorderLayout() );
159         content.setBorder( javax.swing.BorderFactory.createEtchedBorder() );
160         content.add( mainPnl, java.awt.BorderLayout.NORTH );
161         getContentPane().add( content, BorderLayout.CENTER );
162         // set title
163         setTitle( "Backend DB Viewer" );
164         // add status bar
165         getContentPane().add( statusBar, BorderLayout.SOUTH );
166         // add menu bar
167         JMenuBar menuBar = new JMenuBar();
168 
169         // --------------------------------------------------------------------
170         // 'Backend' Menu
171         // --------------------------------------------------------------------
172         
173         JMenu backendMenu = new JMenu( "Backend" );
174         backendMenu.setText( "Backend" );
175         backendMenu.setBackground( new java.awt.Color( 205, 205, 205 ) );
176         backendMenu.setMnemonic( 'B' );
177 
178         // create Import menu item
179         JMenuItem add = new JMenuItem( "Add" );
180         backendMenu.add( add );
181         add.setMnemonic( 'A' );
182         add.setBackground( new java.awt.Color( 205, 205, 205 ) );
183         add.addActionListener( new ActionListener()
184         {
185             public void actionPerformed( ActionEvent e ) 
186             {
187                 doAddDialog();
188             }
189         } );
190 
191         // create Import menu item
192         JMenuItem importItem = new JMenuItem( "Import" );
193         backendMenu.add( importItem );
194         importItem.setMnemonic( 'I' );
195         importItem.setBackground( new java.awt.Color( 205, 205, 205 ) );
196         importItem.addActionListener( new ActionListener()
197         {
198             public void actionPerformed( ActionEvent e ) 
199             {
200                 doImport();
201             }
202         } );
203 
204         // create Exit menu item
205         JMenuItem exit = new JMenuItem( "Exit" );
206         backendMenu.add( exit );
207         exit.setMnemonic( 'E' );
208         exit.setBackground( new java.awt.Color( 205, 205, 205 ) );
209         exit.addActionListener( new ActionListener()
210         {
211             public void actionPerformed( ActionEvent e ) 
212             {
213                 exitForm();
214             }
215         } );
216 
217         // create About menu item
218         JMenu helpMenu = new JMenu( "Help" );
219         helpMenu.setMnemonic( 'H' );
220         JMenuItem about = new JMenuItem( "About" );
221         about.setMnemonic( 'A' );
222         about.setBackground( new java.awt.Color( 205,205,205 ) );
223         about.addActionListener( new ActionListener()
224         {
225             public void actionPerformed( ActionEvent e ) 
226             {
227                 AboutDialog aboutDialog = 
228                     new AboutDialog ( MainFrame.this, true );
229                 MainFrame.this.centerOnScreen( aboutDialog );
230                 aboutDialog.setVisible( true );
231             }
232         } );
233         helpMenu.setBackground( new java.awt.Color( 205,205,205 ) );
234         helpMenu.add( about );
235         
236         // create Save menu item
237         // create Print menu item
238         menuBar.setBackground( new java.awt.Color( 196,197,203 ) );
239         menuBar.add( backendMenu );
240         menuBar.add( searchMenu );
241         menuBar.add( indices );
242         menuBar.add( helpMenu );
243         // sets menu bar
244         setJMenuBar( menuBar );
245         setBounds( new java.awt.Rectangle( 0, 0, 802, 515 ) );
246         setSize( new java.awt.Dimension( 802,515 ) );
247         setResizable( true );
248         
249         addWindowListener( new java.awt.event.WindowAdapter() 
250         {
251             public void windowClosing( java.awt.event.WindowEvent evt ) 
252             {
253                 exitForm();
254             }
255         } );
256         
257         treePane.getViewport().add( tree );
258         tree.setBounds( new java.awt.Rectangle( 6,184,82,80 ) );
259         tree.setShowsRootHandles( true );
260         tree.setToolTipText( "DB DIT" );
261         tree.setScrollsOnExpand( true );
262         tree.getSelectionModel().addTreeSelectionListener(
263             new TreeSelectionListener() 
264         {
265             public void valueChanged( TreeSelectionEvent e ) 
266             {
267                 TreePath path = e.getNewLeadSelectionPath();
268 
269                 if ( path == null )
270                 {
271                     return;
272                 }
273 
274                 Object last = path.getLastPathComponent();
275                 try 
276                 {
277                     if ( last instanceof EntryNode )
278                     {
279                         displayEntry( ( ( EntryNode ) last ).getEntryId(),
280                         ( ( EntryNode ) last).getLdapEntry() );
281                     }
282                 } 
283                 catch( Exception ex ) 
284                 {
285                     ex.printStackTrace();
286                 }
287             }
288         } );
289 
290         entryPane.getViewport().add( entryTbl );
291         entryTbl.setBounds( new java.awt.Rectangle( 321,103,32,32 ) );
292 
293         idxPane.getViewport().add( idxTbl );
294         idxTbl.setBounds( new java.awt.Rectangle( 429,134,32,32 ) );
295 
296         treePane.setSize( new java.awt.Dimension( 285, 435 ) );
297         treePane.setPreferredSize( new java.awt.Dimension( 285, 403 ) );
298         searchMenu.setText( "Search" );
299         searchMenu.setBackground( new java.awt.Color( 205,205,205 ) );
300         searchMenu.add( run );
301         searchMenu.add( debug );
302         searchMenu.add( annotate );
303 
304         ActionListener searchHandler = new ActionListener()
305         {
306             public void actionPerformed( ActionEvent an_event ) 
307             {
308                 if (log.isDebugEnabled())
309                     log.debug( "action command = " + an_event.getActionCommand() );
310 
311                 try
312                 {
313                     doFilterDialog( an_event.getActionCommand() );
314                 }
315                 catch( NamingException e )
316                 {
317                     e.printStackTrace();
318                 }
319             }
320         };
321 
322         annotate.setText( FilterDialog.ANNOTATE_MODE );
323         annotate.setActionCommand( FilterDialog.ANNOTATE_MODE );
324         annotate.setBackground( new java.awt.Color( 205,205,205 ) );
325         annotate.addActionListener( searchHandler );
326 
327         run.setText( FilterDialog.RUN_MODE );
328         run.setActionCommand( FilterDialog.RUN_MODE );
329         run.setBackground( new java.awt.Color( 205,205,205 ) );
330         run.addActionListener( searchHandler );
331 
332         debug.setText( FilterDialog.DEBUG_MODE );
333         debug.setActionCommand( FilterDialog.DEBUG_MODE );
334         debug.setBackground( new java.awt.Color( 205,205,205 ) );
335         debug.addActionListener( searchHandler );
336 
337         indices.setText( "Indices" );
338         indices.setBackground( new java.awt.Color( 205, 205, 205 ) );
339     }
340 
341 
342     private void centerOnScreen( Window window )
343     {
344         Dimension frameSize = window.getSize();
345         Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
346         
347         frameSize.height = ( ( frameSize.height > screenSize.height )
348             ? screenSize.height : frameSize.height );
349         frameSize.width = ( ( frameSize.width > screenSize.width )
350             ? screenSize.width : frameSize.width );
351         window.setLocation( ( screenSize.width - frameSize.width ) / 2,
352             ( screenSize.height - frameSize.height ) / 2 );
353     }
354 
355     
356     /***
357      * Displays a entry addition dialog.
358      */
359     public void doAddDialog()
360     {
361         try 
362         {
363             TreePath path = tree.getSelectionModel().getSelectionPath();
364             String parentDn = partition.getSuffix( false ).toString();
365 
366             if ( null != path )
367             {
368                 Object last = path.getLastPathComponent();
369 
370                 if( last instanceof EntryNode )
371                 {
372                     parentDn = ( ( EntryNode ) last ).getEntryDn();
373                 } 
374             }
375             
376             if ( null == parentDn )
377             {
378                 JOptionPane.showMessageDialog( this, 
379                     "Must select a parent entry to add a child to!" );
380                 return;
381             }
382         
383             AddEntryDialog dialog = new AddEntryDialog( this, false );
384             dialog.setParentDn( parentDn );
385             
386             centerOnScreen( dialog );
387             dialog.setEnabled( true );
388             dialog.setVisible( true );
389         }
390         catch ( Exception e )
391         {
392             e.printStackTrace();
393         }
394     }
395     
396 
397     /***
398      * Gets the DN of the DIT node selected in the tree view.
399      * 
400      * @return the DN of the selected tree node or the root Dn of the tree if 
401      * nothing has been selected yet.
402      */
403     public String getSelectedDn() throws NamingException
404     {
405         TreePath path = tree.getSelectionModel().getSelectionPath();
406         
407         if ( null == path )
408         {
409             return partition.getSuffix( false ).toString();
410         }        
411         
412         Object last = path.getLastPathComponent();
413         String base = null;
414         
415         if( last instanceof EntryNode )
416         {
417             try
418             {
419                 base = ( ( EntryNode ) last ).getEntryDn();
420             }
421             catch ( NamingException e )
422             {
423                 e.printStackTrace();
424             }
425         } 
426         else 
427         {
428             base = partition.getSuffix( false ).toString();
429         }
430         
431         return base;
432     }
433     
434 
435     public void doImport()
436     {
437         FileReader in = null;
438         LdifIterator list = null;
439         LdifParser parser = new LdifParserImpl();
440         JFileChooser chooser = new JFileChooser();
441         int choice = chooser.showOpenDialog( this );
442         File selected = chooser.getSelectedFile();
443         
444         if ( JFileChooser.APPROVE_OPTION != choice )
445         {
446             return;
447         }
448 
449         try 
450         {
451             in = new FileReader( selected );
452             list = new LdifIterator( in );
453             
454             while ( list.hasNext() )
455             {
456                 String dif = ( String ) list.next();
457                 LockableAttributesImpl attrs = new LockableAttributesImpl();
458                 parser.parse( attrs, dif );
459                 String updn = ( String ) attrs.get( "dn" ).get();
460                 LdapName ndn =
461                     new LdapName( StringTools.deepTrimToLower( updn ) );
462                 attrs.remove( "dn" );
463 
464                 if ( null == partition.getEntryId( ndn.toString() ) )
465                 {
466                     partition.add( updn, ndn, attrs );
467                     load();
468                 }
469             }
470         }
471         catch( NamingException e )
472         {
473             // @todo display popup with error here!
474             e.printStackTrace();
475             return;
476         } 
477         catch( FileNotFoundException e ) 
478         {
479             // @todo display popup with error here!
480             e.printStackTrace();
481             return;
482         }
483         catch( IOException e ) 
484         {
485             // @todo display popup with error here!
486             e.printStackTrace();
487             return;
488         }
489         catch( Exception e ) 
490         {
491             // @todo display popup with error here!
492             e.printStackTrace();
493             return;
494         }
495     }
496 
497 
498     /***
499      * Exit the Application
500      */
501     private void exitForm() 
502     {
503         setEnabled( false );
504         setVisible( false );
505         dispose();
506 
507         if ( doCleanUp && partition != null )
508         {
509             try
510             {
511                 partition.sync();
512                 partition.destroy();
513             }
514             catch ( NamingException e )
515             {
516                 e.printStackTrace();
517             }
518 
519 	        System.exit( 0 );
520         }
521     }
522     
523     
524     public void doRunDebugAnnotate( FilterDialog dialog, String mode )
525     {
526         try 
527         {
528             if ( mode == FilterDialog.RUN_MODE )
529             {
530                 doRun( dialog.getFilter(), dialog.getScope(),
531                     dialog.getBase(), dialog.getLimit() );
532             } 
533             else if ( mode == FilterDialog.DEBUG_MODE )
534             {
535                 doDebug( dialog.getFilter(), dialog.getScope(),
536                      dialog.getBase(), dialog.getLimit() );
537             } 
538             else if ( mode == FilterDialog.ANNOTATE_MODE )
539             {
540                 if ( doAnnotate( dialog.getFilter() ) )
541                 {
542                     // continue
543                 } 
544                 else 
545                 {
546                     // We failed don't loose users filter buf
547                     // allow user to make edits.
548                     return;
549                 }
550             } 
551             else 
552             {
553                 throw new RuntimeException( "Unrecognized mode." );
554             }
555         }
556         catch ( Exception e )
557         {
558             // @todo show error popup here!
559             e.printStackTrace();
560         }
561     }
562 
563 
564     public void doFilterDialog( final String mode ) throws NamingException
565     {
566         final FilterDialog dialog = new FilterDialog( mode, this, true );
567 
568         if ( tree.getSelectionModel().getSelectionPath() != null )
569         {
570             dialog.setBase( getSelectedDn() );
571         } 
572         else 
573         {
574             dialog.setBase( partition.getSuffix( false ).toString() );
575         }
576 
577         dialog.addActionListener( new ActionListener()
578         {
579             public void actionPerformed( ActionEvent an_event ) 
580             {
581                 String cmd = an_event.getActionCommand();
582 
583                 if ( cmd.equals( FilterDialog.SEARCH_CMD ) )
584                 {
585                     doRunDebugAnnotate( dialog, mode );
586                 } 
587                 else if ( cmd.equals(FilterDialog.CANCEL_CMD ) )
588                 {
589                     // Do nothing! Just exit dialog.
590                 } 
591                 else 
592                 {
593                     throw new RuntimeException( 
594                         "Unrecognized FilterDialog command: " + cmd );
595                 }
596 
597 				dialog.setVisible( false );
598 				dialog.dispose();
599             }
600         } );
601 
602         //Center the frame on screen
603         dialog.setSize( 456, 256 );
604         centerOnScreen( dialog );
605         dialog.setEnabled( true );
606         dialog.setVisible( true );
607     } 
608 
609 
610     public boolean doRun( String filter, String scope, String base,
611         String limit )
612         throws Exception
613     {
614         if (log.isDebugEnabled())
615         {
616             log.debug( "Search attempt using filter '" + filter + "' "
617             + "with scope '" + scope + "' and a return limit of '" + limit
618             + "'" );
619         }
620 
621         FilterParser parser = new FilterParserImpl();
622         ExprNode root = null;
623 
624         try 
625         {
626             root = parser.parse( filter );
627         } 
628         catch ( Exception e ) 
629         {
630             e.printStackTrace();
631             JTextArea text = new JTextArea();
632             String msg = e.getMessage();
633 
634             if ( msg.length() > 1024 )
635             {
636                 msg = msg.substring( 0, 1024 ) + "\n. . . truncated . . .";
637             }
638 
639             text.setText( msg );
640             text.setEnabled( false );
641             JOptionPane.showMessageDialog( null, text, "Syntax Error",
642                 JOptionPane.ERROR_MESSAGE );
643             return false;
644         }
645 
646         SearchControls ctls = new SearchControls();
647 
648         if ( scope == FilterDialog.BASE_SCOPE )
649         {
650 	        ctls.setSearchScope( SearchControls.OBJECT_SCOPE );
651         } 
652         else if ( scope == FilterDialog.SINGLE_SCOPE )
653         {
654             ctls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
655         } 
656         else if ( scope == FilterDialog.SUBTREE_SCOPE )
657         {
658             ctls.setSearchScope( SearchControls.SUBTREE_SCOPE );
659         } else {
660             throw new RuntimeException( "Unexpected scope parameter: " +
661                 scope );
662         }
663 
664         int limitMax = Integer.MAX_VALUE;
665         if ( ! limit.equals( FilterDialog.UNLIMITED ) )
666         {
667             limitMax = Integer.parseInt( limit );
668         }
669 
670         Hashtable env = new Hashtable();
671 
672         env.put( DerefAliasesEnum.JNDI_PROP,
673             DerefAliasesEnum.DEREFALWAYS_NAME );
674 
675         NamingEnumeration cursor = eng.search( new LdapName( base ),
676                 env, root, ctls );
677         String [] cols = new String [2];
678         cols[0] = "id";
679         cols[1] = "dn";
680         DefaultTableModel tableModel = new DefaultTableModel( cols, 0 );
681         Object [] row = new Object[2];
682         int count = 0;
683         while ( cursor.hasMore() && count < limitMax )
684         {
685             IndexRecord rec = ( IndexRecord ) cursor.next();
686             row[0] = rec.getEntryId();
687             row[1] = partition.getEntryDn( ( BigInteger ) row[0] );
688             tableModel.addRow( row );
689             count++;
690         }
691 
692         SearchResultDialog results = new SearchResultDialog( this, false );
693         StringBuffer buf = new StringBuffer();
694         buf.append( "base: " );
695         buf.append( base );
696         buf.append( "\n" );
697         buf.append( "scope: " );
698         buf.append( scope );
699         buf.append( "\n" );
700         buf.append( "limit: " );
701         buf.append( limit );
702         buf.append( "\n" );
703         buf.append( "total: " );
704         buf.append( count );
705         buf.append( "\n" );
706         buf.append( "filter:\n" );
707         buf.append( filter );
708         buf.append( "\n" );
709         results.setFilter( buf.toString() );
710 
711         TreeNode astRoot = new ASTNode( null, root );
712         TreeModel treeModel = new DefaultTreeModel( astRoot, true );
713         results.setTreeModel( treeModel );
714         results.setTableModel( tableModel );
715         centerOnScreen( results );
716         results.setVisible( true );
717         return true;
718     }
719 
720 
721     public void doDebug( String filter, String scope, String base,
722         String limit )
723     {
724         if (log.isDebugEnabled())
725         {
726             log.debug( "Search attempt using filter '" + filter + "' "
727             + "with scope '" + scope + "' and a return limit of '" + limit
728             + "'" );
729         }
730     }
731 
732 
733     public void selectTreeNode( BigInteger id )
734     {
735         Stack stack = new Stack();
736         Object [] comps = null;
737         TreeNode parent = ( EntryNode ) nodes.get( id );
738 
739         while ( parent != null && ( parent != parent.getParent() ) )
740         {
741             stack.push( parent );
742             parent = parent.getParent();
743         }
744 
745         if ( stack.size() == 0 )
746         {
747             comps = new Object[1];
748             comps[0] = root;
749         } 
750         else 
751         {
752             comps = new Object[stack.size()];
753         }
754 
755         for ( int ii = 0; stack.size() > 0 && ii < comps.length; ii++ )
756         {
757             comps[ii] = stack.pop();
758         }
759 
760         TreePath path = new TreePath( comps );
761         tree.scrollPathToVisible( path );
762         tree.getSelectionModel().setSelectionPath( path );
763         tree.validate();
764     }
765 
766 
767     public boolean doAnnotate( String filter )
768         throws Exception
769     {
770 		FilterParser parser = new FilterParserImpl();
771         ExprNode root = null;
772 
773         try 
774         {
775             root = parser.parse( filter );
776         } 
777         catch( Exception e ) 
778         {
779             JTextArea text = new JTextArea();
780             String msg = e.getMessage();
781 
782             if ( msg.length() > 1024 )
783             {
784                 msg = msg.substring( 0, 1024 ) + "\n. . . truncated . . .";
785             }
786 
787             text.setText( msg );
788             text.setEnabled( false );
789             JOptionPane.showMessageDialog( null, text, "Syntax Error",
790                 JOptionPane.ERROR_MESSAGE );
791             return false;
792         }
793 
794 		AnnotatedFilterTreeDialog treeDialog = new
795 			AnnotatedFilterTreeDialog( MainFrame.this, false );
796 		treeDialog.setFilter( filter );
797 
798         eng.getOptimizer().annotate( root );
799 		TreeNode astRoot = new ASTNode( null, root );
800 		TreeModel model = new DefaultTreeModel( astRoot, true );
801 		treeDialog.setModel( model );
802         treeDialog.setVisible( true );
803         return true;
804     }
805 
806 
807     /***
808      * Shows a dialog to display and scan indices.
809      * 
810      * @param idxAttr the name of the index or its attribute
811      * @throws Exception if the indices cannot be accessed
812      */
813     public void showIndexDialog( String idxAttr )
814         throws Exception
815     {
816         Index index = null;
817         boolean isSystem = partition.hasSystemIndexOn( idxAttr );
818         
819         if ( isSystem )
820         {
821             index = partition.getSystemIndex( idxAttr );
822         }
823         else 
824         {
825             index = partition.getUserIndex( idxAttr );
826         }
827 
828         if ( index != null )
829         {
830             IndexDialog dialog = new IndexDialog( this, false, index );
831             centerOnScreen( dialog );
832             dialog.setEnabled( true );
833             dialog.setVisible( true );
834         }
835     }
836 
837 
838     public void buildIndicesMenu( BTreeContextPartition partition )
839     {
840         JMenuItem item = null;
841         
842         ActionListener listener = new ActionListener()
843         {
844             public void actionPerformed( ActionEvent event )
845             {
846                 try 
847                 {
848                     showIndexDialog( event.getActionCommand() );
849                 } 
850                 catch ( Exception e ) 
851                 {
852                     e.printStackTrace();
853                 }
854             }
855         };
856 
857         Iterator list = partition.getSystemIndices();
858         while ( list.hasNext() )
859         {
860             String idx = ( String ) list.next();
861             item = new JMenuItem();
862             item.setBackground( new java.awt.Color( 205, 205, 205 ) );
863             indices.add( item );
864             item.setText( idx );
865             item.setActionCommand( idx );
866             item.addActionListener( listener );
867         }
868 
869         indices.add( new JSeparator() );
870         list = partition.getUserIndices();
871         while ( list.hasNext() )
872         {
873             String idx = ( String ) list.next();
874 			item = new JMenuItem();
875             item.setBackground( new java.awt.Color( 205, 205, 205 ) );
876             indices.add( item );
877             item.setText( idx );
878             item.setActionCommand( idx );
879             item.addActionListener( listener );
880         }
881     }
882 
883 
884     void displayEntry( BigInteger id, Attributes entry )
885         throws Exception
886     {
887         String dn = partition.getEntryUpdn( id );
888         AttributesTableModel model =
889             new AttributesTableModel( entry, id, dn, false );
890         entryTbl.setModel( model );
891 
892         model = new AttributesTableModel(
893             partition.getIndices( id ), id, dn, false );
894         idxTbl.setModel( model );
895 
896         validate();
897     }
898 
899 
900     private void load() throws NamingException
901     {
902         // boolean doFiltered = false;
903         nodes = new HashMap();
904 
905         Attributes suffix = partition.getSuffixEntry();
906         BigInteger id = partition.getEntryId(
907             partition.getSuffix( false ).toString() );
908         root = new EntryNode( id, null, partition, suffix, nodes );
909 
910         /*
911         int option = JOptionPane.showConfirmDialog( null,
912             "Would you like to filter leaf nodes on load?", "Use Filter?",
913             JOptionPane.OK_CANCEL_OPTION );
914         doFiltered = option == JOptionPane.OK_OPTION;
915 
916         if(doFiltered) {
917             SearchEngine engine = new SearchEngine();
918             final FilterDialog dialog =
919                 new FilterDialog(FilterDialog.LOAD_MODE, this, true);
920             dialog.addActionListener(new ActionListener() {
921                 public void actionPerformed(ActionEvent e) {
922                     dialog.setVisible(false);
923                     dialog.dispose();
924                 }
925             });
926 
927             dialog.setBase(database.getSuffix().toString());
928             dialog.setScope(FilterDialog.SUBTREE_SCOPE);
929 
930             //Center the frame on screen
931             dialog.setSize(456, 256);
932             this.centerOnScreen( dialog );
933             dialog.setEnabled(true);
934             dialog.setVisible(true);
935 
936             FilterParser parser = new FilterParserImpl();
937             parser.enableLogging(logger);
938             ExprNode exprNode = parser.parse(dialog.getFilter());
939 
940             int scope = -1;
941             String scopeStr = dialog.getScope();
942             if(scopeStr == FilterDialog.BASE_SCOPE) {
943                 scope = Backend.BASE_SCOPE;
944             } else if(scopeStr == FilterDialog.SINGLE_SCOPE) {
945                 scope = Backend.SINGLE_SCOPE;
946             } else if(scopeStr == FilterDialog.SUBTREE_SCOPE) {
947                 scope = Backend.SUBTREE_SCOPE;
948             } else {
949                 throw new RuntimeException("Unrecognized scope");
950             }
951 
952             exprNode =
953                 engine.addScopeNode(exprNode, dialog.getBase(), scope);
954             root = new EntryNode(null, database,
955                 database.getSuffixEntry(), nodes, exprNode, engine);
956         } else {
957             root = new EntryNode(null, database,
958                 database.getSuffixEntry(), nodes);
959         }
960         */
961 
962         DefaultTreeModel model = new DefaultTreeModel( root );
963         tree.setModel( model );
964 
965         if ( isVisible() ) 
966         {
967             tree.validate();
968         }
969     }
970 }