001    /*
002    // $Id: //open/mondrian/src/main/mondrian/gui/Workbench.java#31 $
003    // This software is subject to the terms of the Common Public License
004    // Agreement, available at the following URL:
005    // http://www.opensource.org/licenses/cpl.html.
006    // Copyright (C) 1999-2002 Kana Software, Inc.
007    // Copyright (C) 2001-2008 Julian Hyde and others
008    // Copyright (C) 2006-2007 Cincom Systems, Inc.
009    // Copyright (C) 2006-2007 JasperSoft
010    // All Rights Reserved.
011    // You must accept the terms of that agreement to use this software.
012    //
013    // Created on September 26, 2002, 11:28 AM
014    // Modified on 15-Jun-2003 by ebengtso
015    //
016     */
017    
018    package mondrian.gui;
019    
020    
021    import java.awt.Dimension;
022    import java.awt.event.ActionEvent;
023    import java.awt.event.ActionListener;
024    import java.awt.event.FocusAdapter;
025    import java.awt.event.FocusEvent;
026    import java.util.Iterator;
027    import java.util.Map;
028    import javax.swing.event.InternalFrameAdapter;
029    import javax.swing.filechooser.FileSystemView;
030    import mondrian.olap.DriverManager;
031    import mondrian.olap.MondrianProperties;
032    
033    import javax.swing.*;
034    
035    import java.io.*;
036    import java.net.MalformedURLException;
037    import java.net.URI;
038    import java.net.URISyntaxException;
039    import java.util.HashMap;
040    import java.util.Locale;
041    import java.util.Properties;
042    import java.util.ResourceBundle;
043    import java.util.MissingResourceException;
044    import java.util.Vector;
045    import javax.swing.event.InternalFrameEvent;
046    import javax.swing.plaf.basic.BasicArrowButton;
047    import javax.swing.text.DefaultEditorKit;
048    
049    import org.apache.log4j.Logger;
050    import org.eigenbase.xom.XMLOutput;
051    
052    /**
053     *
054     * @author  sean
055     * @version $Id: //open/mondrian/src/main/mondrian/gui/Workbench.java#31 $
056     */
057    public class Workbench extends javax.swing.JFrame {
058    
059        static String WORKBENCH_USER_HOME_DIR;
060        static String WORKBENCH_CONFIG_FILE;
061    
062        private static final String LAST_USED1 = "lastUsed1";
063        private static final String LAST_USED1_URL = "lastUsedUrl1";
064        private static final String LAST_USED2 = "lastUsed2";
065        private static final String LAST_USED2_URL = "lastUsedUrl2";
066        private static final String LAST_USED3 = "lastUsed3";
067        private static final String LAST_USED3_URL = "lastUsedUrl3";
068        private static final String LAST_USED4 = "lastUsed4";
069        private static final String LAST_USED4_URL = "lastUsedUrl4";
070        private static final String WorkbenchInfoResourceName = "mondrian.gui.resources.workbenchInfo";
071        private static final String GUIResourceName = "mondrian.gui.resources.gui";
072        private static final String TextResourceName = "mondrian.gui.resources.text";
073    
074        private static final Logger LOGGER = Logger.getLogger(Workbench.class);
075    
076        private String jdbcDriverClassName;
077        private String jdbcConnectionUrl;
078        private String jdbcUsername;
079        private String jdbcPassword;
080    
081        private JDBCMetaData jdbcMetaData;
082    
083        private final ClassLoader myClassLoader;
084    
085        private final ResourceBundle guiResourceBundle;
086        private final ResourceBundle textResourceBundle;
087    
088        private Properties workbenchProperties;
089        private static ResourceBundle workbenchResourceBundle = null;
090    
091        private I18n resourceConverter = null;
092    
093        private static int newSchema = 1;
094    
095        private String openFile = null;
096    
097        private Map schemaWindowMap = new HashMap();    // map of schema frames and its menu items (JInternalFrame -> JMenuItem)
098        private Vector mdxWindows = new Vector();
099        private int windowMenuMapIndex = 1;
100    
101        /** Creates new form Workbench */
102        public Workbench() {
103            myClassLoader = this.getClass().getClassLoader();
104    
105            guiResourceBundle = ResourceBundle.getBundle(GUIResourceName, Locale.getDefault(), myClassLoader);
106            textResourceBundle = ResourceBundle.getBundle(TextResourceName, Locale.getDefault(), myClassLoader);
107    
108            resourceConverter = new I18n(guiResourceBundle, textResourceBundle);
109    
110            // Setting User home directory
111            WORKBENCH_USER_HOME_DIR = System.getProperty("user.home") + File.separator + ".schemaWorkbench";
112            WORKBENCH_CONFIG_FILE = WORKBENCH_USER_HOME_DIR + File.separator + "workbench.properties";
113    
114            loadWorkbenchProperties();
115            initDataSource();
116            initComponents();
117            loadMenubarPlugins();
118    
119            ImageIcon icon = new javax.swing.ImageIcon(myClassLoader.getResource(resourceConverter.getGUIReference("cube")));
120    
121            this.setIconImage(icon.getImage());
122        }
123    
124        /**
125         * load properties
126         */
127        private void loadWorkbenchProperties() {
128            workbenchProperties = new Properties();
129            try {
130                workbenchResourceBundle = ResourceBundle.getBundle(WorkbenchInfoResourceName, Locale.getDefault(), myClassLoader);
131    
132                File f = new File(WORKBENCH_CONFIG_FILE);
133                if (f.exists()) {
134                    workbenchProperties.load(new FileInputStream(f));
135                } else {
136                    LOGGER.debug(WORKBENCH_CONFIG_FILE + " does not exist");
137                }
138            } catch (Exception e) {
139                // TODO deal with exception
140                LOGGER.error("loadWorkbenchProperties", e);
141    
142            }
143        }
144    
145        /**
146         * returns the value of a workbench property
147         *
148         * @param key key to lookup
149         * @return the value
150         */
151        public String getWorkbenchProperty(String key) {
152            return workbenchProperties.getProperty(key);
153        }
154    
155        /**
156         * set a workbench property.  Note that this does not save the property,
157         * a call to storeWorkbenchProperties is required.
158         *
159         * @param key property key
160         * @param value property value
161         */
162        public void setWorkbenchProperty(String key, String value) {
163            workbenchProperties.setProperty(key, value);
164        }
165    
166        /**
167         * save properties
168         */
169        public void storeWorkbenchProperties() {
170            //save properties to file
171            File dir = new File(WORKBENCH_USER_HOME_DIR);
172            try {
173                if (dir.exists()) {
174                    if (!dir.isDirectory()) {
175                        JOptionPane.showMessageDialog(this,
176                                getResourceConverter().getFormattedString("workbench.user.home.not.directory",
177                                            "{0} is not a directory!\nPlease rename this file and retry to save configuration!", new String[] {WORKBENCH_USER_HOME_DIR}),
178                                            "", JOptionPane.ERROR_MESSAGE);
179                        return;
180                    }
181                } else {
182                    dir.mkdirs();
183                }
184            } catch (Exception ex) {
185                LOGGER.error("storeWorkbenchProperties: mkdirs", ex);
186                JOptionPane.showMessageDialog(this,
187                        getResourceConverter().getFormattedString("workbench.user.home.exception",
188                                "An error is occurred creating workbench configuration directory:\n{0}\nError is: {1}",
189                                    new String[] {WORKBENCH_USER_HOME_DIR, ex.getLocalizedMessage()}),
190                                "", JOptionPane.ERROR_MESSAGE);
191                return;
192            }
193    
194            OutputStream out = null;
195            try {
196                out = (OutputStream) new FileOutputStream(new File(WORKBENCH_CONFIG_FILE));
197                workbenchProperties.store(out, "Workbench configuration");
198            } catch (Exception e) {
199                LOGGER.error("storeWorkbenchProperties: store", e);
200                JOptionPane.showMessageDialog(this,
201                        getResourceConverter().getFormattedString("workbench.save.configuration",
202                                "An error is occurred creating workbench configuration file:\n{0}\nError is: {1}",
203                                new String[] {WORKBENCH_CONFIG_FILE, e.getLocalizedMessage()}),
204                                "", JOptionPane.ERROR_MESSAGE);
205            } finally {
206                try {
207                    out.close();
208                } catch (IOException eIO) {
209                    LOGGER.error("storeWorkbenchProperties: out.close", eIO);
210                }
211            }
212        }
213    
214        /**
215         * Initialize the data source from a property file
216         */
217        private void initDataSource() {
218            jdbcDriverClassName = workbenchProperties.getProperty("jdbcDriverClassName");
219            jdbcConnectionUrl = workbenchProperties.getProperty("jdbcConnectionUrl");
220            jdbcUsername = workbenchProperties.getProperty("jdbcUsername");
221            jdbcPassword = workbenchProperties.getProperty("jdbcPassword");
222        }
223    
224        /** This method is called from within the constructor to
225         * initialize the form.
226         */
227        private void initComponents() {
228            desktopPane = new javax.swing.JDesktopPane();
229            jToolBar1 = new javax.swing.JToolBar();
230            jToolBar2 = new javax.swing.JToolBar();
231            toolbarNewPopupMenu = new JPopupMenu();
232            toolbarNewButton = new javax.swing.JButton();
233            toolbarOpenButton = new javax.swing.JButton();
234            toolbarSaveButton = new javax.swing.JButton();
235            toolbarSaveAsButton = new javax.swing.JButton();
236            jPanel1 = new javax.swing.JPanel();
237            jPanel2 = new javax.swing.JPanel();
238            toolbarPreferencesButton = new javax.swing.JButton();
239            menuBar = new javax.swing.JMenuBar();
240            fileMenu = new javax.swing.JMenu();
241            newMenu = new javax.swing.JMenu();
242            newSchemaMenuItem = new javax.swing.JMenuItem();
243            newQueryMenuItem = new javax.swing.JMenuItem();
244            newJDBCExplorerMenuItem = new javax.swing.JMenuItem();
245            newSchemaMenuItem2 = new javax.swing.JMenuItem();
246            newQueryMenuItem2 = new javax.swing.JMenuItem();
247            newJDBCExplorerMenuItem2 = new javax.swing.JMenuItem();
248            openMenuItem = new javax.swing.JMenuItem();
249            preferencesMenuItem = new javax.swing.JMenuItem();
250            lastUsed1MenuItem = new javax.swing.JMenuItem();
251            lastUsed2MenuItem = new javax.swing.JMenuItem();
252            lastUsed3MenuItem = new javax.swing.JMenuItem();
253            lastUsed4MenuItem = new javax.swing.JMenuItem();
254            saveMenuItem = new javax.swing.JMenuItem();
255            saveAsMenuItem = new javax.swing.JMenuItem();
256            jSeparator1 = new javax.swing.JSeparator();
257            jSeparator2 = new javax.swing.JSeparator();
258            jSeparator3 = new javax.swing.JSeparator();
259            jSeparator4 = new javax.swing.JSeparator();
260            exitMenuItem = new javax.swing.JMenuItem();
261            windowMenu = new javax.swing.JMenu();
262            helpMenu = new javax.swing.JMenu();
263            editMenu = new javax.swing.JMenu();
264            cutMenuItem = new javax.swing.JMenuItem(new DefaultEditorKit.CutAction());
265            copyMenuItem = new javax.swing.JMenuItem(new DefaultEditorKit.CopyAction());
266            pasteMenuItem = new javax.swing.JMenuItem(new DefaultEditorKit.PasteAction());
267            deleteMenuItem = new javax.swing.JMenuItem();
268            aboutMenuItem = new javax.swing.JMenuItem();
269            toolsMenu = new javax.swing.JMenu();
270            viewMenu = new javax.swing.JMenu();
271            viewDimensionsMenuItem = new javax.swing.JCheckBoxMenuItem();
272            viewMeasuresMenuItem = new javax.swing.JCheckBoxMenuItem();
273            viewCubesMenuItem = new javax.swing.JCheckBoxMenuItem();
274            viewXMLMenuItem = new javax.swing.JCheckBoxMenuItem();
275    
276            setTitle(getResourceConverter().getString("workbench.panel.title","Schema Workbench"));
277            setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
278            addWindowListener(new java.awt.event.WindowAdapter() {
279                public void windowClosing(java.awt.event.WindowEvent evt) {
280                    storeWorkbenchProperties();
281                    closeAllSchemaFrames(true);
282                }
283            });
284    
285            getContentPane().add(desktopPane, java.awt.BorderLayout.CENTER);
286    
287    
288            newSchemaMenuItem2.setText(getResourceConverter().getString("workbench.menu.newSchema","Schema"));
289            //newSchemaMenuItem2.setText("Schema");
290            newSchemaMenuItem2.addActionListener(new java.awt.event.ActionListener() {
291                public void actionPerformed(java.awt.event.ActionEvent evt) {
292                    newSchemaMenuItemActionPerformed(evt);
293                }
294            });
295    
296    
297            newQueryMenuItem2.setText(getResourceConverter().getString("workbench.menu.newQuery","MDX Query"));
298            //newQueryMenuItem2.setText("MDX Query");
299            newQueryMenuItem2.addActionListener(new java.awt.event.ActionListener() {
300                public void actionPerformed(java.awt.event.ActionEvent evt) {
301                    newQueryMenuItemActionPerformed(evt);
302                }
303            });
304    
305    
306            newJDBCExplorerMenuItem2.setText(getResourceConverter().getString("workbench.menu.newJDBC","JDBC Explorer"));
307            //newJDBCExplorerMenuItem2.setText("JDBC Explorer");
308            newJDBCExplorerMenuItem2.addActionListener(new java.awt.event.ActionListener() {
309                public void actionPerformed(java.awt.event.ActionEvent evt) {
310                    newJDBCExplorerMenuItemActionPerformed(evt);
311                }
312            });
313    
314    
315            toolbarNewPopupMenu.add(newSchemaMenuItem2);
316            toolbarNewPopupMenu.add(newQueryMenuItem2);
317            toolbarNewPopupMenu.add(newJDBCExplorerMenuItem2);
318    
319    
320            jPanel2.setLayout(new java.awt.BorderLayout());
321            jPanel2.setBorder(javax.swing.BorderFactory.createEtchedBorder());
322            jPanel2.setMaximumSize(new java.awt.Dimension(50, 28)); // old width=18
323    
324            toolbarNewButton.setIcon(new javax.swing.ImageIcon(getClass().getResource(resourceConverter.getGUIReference("new"))));
325            toolbarNewButton.setToolTipText(getResourceConverter().getString("workbench.toolbar.new","New"));
326            //toolbarNewButton.setToolTipText("New");
327            toolbarNewButton.setBorderPainted(false);
328            toolbarNewButton.addActionListener(new ActionListener() {
329                public void actionPerformed(ActionEvent e) {
330                    toolbarNewPopupMenu.show(jPanel2,0,jPanel2.getSize().height);
331                }
332            });
333    
334            jToolBar2.setFloatable(false);
335            jToolBar2.add(toolbarNewButton);
336    
337            jPanel2.add(jToolBar2,java.awt.BorderLayout.CENTER);
338    
339            toolbarNewArrowButton = new BasicArrowButton(SwingConstants.SOUTH);
340            toolbarNewArrowButton.setToolTipText(getResourceConverter().getString("workbench.toolbar.newArrow","New"));
341            //toolbarNewArrowButton.setToolTipText("New");
342            toolbarNewArrowButton.setBorderPainted(false);
343            toolbarNewArrowButton.addActionListener(new ActionListener() {
344                public void actionPerformed(ActionEvent e) {
345                    toolbarNewPopupMenu.show(jPanel2,0,jPanel2.getSize().height);
346                }
347            });
348    
349            jPanel2.add(toolbarNewArrowButton,java.awt.BorderLayout.EAST);
350    
351            // toolbarNewButton.add(select); // error:none of the toolbar buttons are displayed
352            // jToolBar1.add(select,1);    //error: arrow button is so wide it takes all remaining space on toolbar
353            jToolBar1.add(jPanel2,0);
354    
355    
356    
357    
358            toolbarOpenButton.setIcon(new javax.swing.ImageIcon(getClass().getResource(resourceConverter.getGUIReference("open"))));
359            toolbarOpenButton.setToolTipText(getResourceConverter().getString("workbench.toolbar.open","Open"));
360            //toolbarOpenButton.setToolTipText("Open");
361            toolbarOpenButton.addActionListener(new java.awt.event.ActionListener() {
362                public void actionPerformed(java.awt.event.ActionEvent evt) {
363                    openMenuItemActionPerformed(evt);
364                }
365            });
366    
367            jToolBar1.add(toolbarOpenButton);
368    
369    
370            toolbarSaveButton.setIcon(new javax.swing.ImageIcon(getClass().getResource(resourceConverter.getGUIReference("save"))));
371            toolbarSaveButton.setToolTipText(getResourceConverter().getString("workbench.toolbar.save","Save"));
372            toolbarSaveButton.addActionListener(new java.awt.event.ActionListener() {
373                public void actionPerformed(java.awt.event.ActionEvent evt) {
374                    saveMenuItemActionPerformed(evt);
375                }
376            });
377    
378            jToolBar1.add(toolbarSaveButton);
379    
380            toolbarSaveAsButton.setIcon(new javax.swing.ImageIcon(getClass().getResource(resourceConverter.getGUIReference("saveAs"))));
381            toolbarSaveAsButton.setToolTipText(getResourceConverter().getString("workbench.toolbar.saveAs","Save As"));
382            toolbarSaveAsButton.addActionListener(new java.awt.event.ActionListener() {
383                public void actionPerformed(java.awt.event.ActionEvent evt) {
384                    saveAsMenuItemActionPerformed(evt);
385                }
386            });
387    
388            jToolBar1.add(toolbarSaveAsButton);
389    
390            jPanel1.setMaximumSize(new java.awt.Dimension(8, 8)); //8, 32767
391            jToolBar1.add(jPanel1);
392    
393            toolbarPreferencesButton.setIcon(new javax.swing.ImageIcon(getClass().getResource(resourceConverter.getGUIReference("preferences"))));
394            toolbarPreferencesButton.setToolTipText(getResourceConverter().getString("workbench.toolbar.preferences","Preferences"));
395            toolbarPreferencesButton.addActionListener(new java.awt.event.ActionListener() {
396                public void actionPerformed(java.awt.event.ActionEvent evt) {
397                    toolbarPreferencesButtonActionPerformed(evt);
398                }
399            });
400    
401            jToolBar1.add(toolbarPreferencesButton);
402    
403    
404            getContentPane().add(jToolBar1, java.awt.BorderLayout.NORTH);
405    
406            fileMenu.setText(getResourceConverter().getString("workbench.menu.file","File"));
407            newMenu.setText(getResourceConverter().getString("workbench.menu.new","New"));
408    
409            newSchemaMenuItem.setText(getResourceConverter().getString("workbench.menu.newSchema","Schema"));
410            newSchemaMenuItem.addActionListener(new java.awt.event.ActionListener() {
411                public void actionPerformed(java.awt.event.ActionEvent evt) {
412                    newSchemaMenuItemActionPerformed(evt);
413                }
414            });
415    
416            newMenu.add(newSchemaMenuItem);
417    
418            newQueryMenuItem.setText(getResourceConverter().getString("workbench.menu.newQuery","MDX Query"));
419            newQueryMenuItem.addActionListener(new java.awt.event.ActionListener() {
420                public void actionPerformed(java.awt.event.ActionEvent evt) {
421                    newQueryMenuItemActionPerformed(evt);
422                }
423            });
424    
425            newMenu.add(newQueryMenuItem);
426    
427            newJDBCExplorerMenuItem.setText(getResourceConverter().getString("workbench.menu.newJDBC","JDBC Explorer"));
428            newJDBCExplorerMenuItem.addActionListener(new java.awt.event.ActionListener() {
429                public void actionPerformed(java.awt.event.ActionEvent evt) {
430                    newJDBCExplorerMenuItemActionPerformed(evt);
431                }
432            });
433    
434            newMenu.add(newJDBCExplorerMenuItem);
435    
436            fileMenu.add(newMenu);
437    
438            openMenuItem.setText(getResourceConverter().getString("workbench.menu.open","Open"));
439            openMenuItem.addActionListener(new java.awt.event.ActionListener() {
440                public void actionPerformed(java.awt.event.ActionEvent evt) {
441                    openMenuItemActionPerformed(evt);
442                }
443            });
444    
445            fileMenu.add(openMenuItem);
446    
447            saveMenuItem.setText(getResourceConverter().getString("workbench.menu.save","Save"));
448            saveMenuItem.addActionListener(new java.awt.event.ActionListener() {
449                public void actionPerformed(java.awt.event.ActionEvent evt) {
450                    saveMenuItemActionPerformed(evt);
451                }
452            });
453    
454            fileMenu.add(saveMenuItem);
455    
456            saveAsMenuItem.setText(getResourceConverter().getString("workbench.menu.saveAsDot","Save As ..."));
457            saveAsMenuItem.addActionListener(new java.awt.event.ActionListener() {
458                public void actionPerformed(java.awt.event.ActionEvent evt) {
459                    saveAsMenuItemActionPerformed(evt);
460                }
461            });
462    
463            fileMenu.add(saveAsMenuItem);
464    
465            //add last used
466            fileMenu.add(jSeparator2);
467    
468            lastUsed1MenuItem.setText(workbenchProperties.getProperty("lastUsed1"));
469            lastUsed1MenuItem.addActionListener(new java.awt.event.ActionListener() {
470                public void actionPerformed(java.awt.event.ActionEvent evt) {
471                    lastUsed1MenuItemActionPerformed(evt);
472                }
473            });
474            fileMenu.add(lastUsed1MenuItem);
475    
476            lastUsed2MenuItem.setText(workbenchProperties.getProperty("lastUsed2"));
477            lastUsed2MenuItem.addActionListener(new java.awt.event.ActionListener() {
478                public void actionPerformed(java.awt.event.ActionEvent evt) {
479                    lastUsed2MenuItemActionPerformed(evt);
480                }
481            });
482            fileMenu.add(lastUsed2MenuItem);
483    
484            lastUsed3MenuItem.setText(workbenchProperties.getProperty("lastUsed3"));
485            lastUsed3MenuItem.addActionListener(new java.awt.event.ActionListener() {
486                public void actionPerformed(java.awt.event.ActionEvent evt) {
487                    lastUsed3MenuItemActionPerformed(evt);
488                }
489            });
490            fileMenu.add(lastUsed3MenuItem);
491    
492            lastUsed4MenuItem.setText(workbenchProperties.getProperty("lastUsed4"));
493            lastUsed4MenuItem.addActionListener(new java.awt.event.ActionListener() {
494                public void actionPerformed(java.awt.event.ActionEvent evt) {
495                    lastUsed4MenuItemActionPerformed(evt);
496                }
497            });
498            fileMenu.add(lastUsed4MenuItem);
499    
500            updateLastUsedMenu();
501            fileMenu.add(jSeparator1);
502    
503            exitMenuItem.setText(getResourceConverter().getString("workbench.menu.exit","Exit"));
504            exitMenuItem.addActionListener(new java.awt.event.ActionListener() {
505                public void actionPerformed(java.awt.event.ActionEvent evt) {
506                    exitMenuItemActionPerformed(evt);
507                }
508            });
509    
510            fileMenu.add(exitMenuItem);
511    
512            menuBar.add(fileMenu);
513    
514            editMenu.setText(getResourceConverter().getString("workbench.menu.edit","Edit"));
515            cutMenuItem.setText(getResourceConverter().getString("workbench.menu.cut","Cut"));
516            editMenu.add(cutMenuItem);
517    
518            copyMenuItem.setText(getResourceConverter().getString("workbench.menu.copy","Copy"));
519            editMenu.add(copyMenuItem);
520    
521            pasteMenuItem.setText(getResourceConverter().getString("workbench.menu.paste","Paste"));
522            editMenu.add(pasteMenuItem);
523    
524            pasteMenuItem.setText(getResourceConverter().getString("workbench.menu.delete","Delete"));
525            editMenu.add(deleteMenuItem);
526    
527            menuBar.add(editMenu);
528            editMenu.add(pasteMenuItem);
529    
530            viewMenu.setText(getResourceConverter().getString("workbench.menu.view","View"));
531            viewXMLMenuItem.setText(getResourceConverter().getString("workbench.menu.viewXML","View XML"));
532            viewXMLMenuItem.addActionListener(new java.awt.event.ActionListener() {
533                public void actionPerformed(java.awt.event.ActionEvent evt) {
534                    viewXMLMenuItemActionPerformed(evt);
535                }
536            });
537            viewMenu.add(viewXMLMenuItem);
538            menuBar.add(viewMenu);
539    
540            toolsMenu.setText(getResourceConverter().getString("workbench.menu.tools","Tools"));
541            preferencesMenuItem.setText(getResourceConverter().getString("workbench.menu.preferences","Preferences"));
542            preferencesMenuItem.addActionListener(new java.awt.event.ActionListener() {
543                public void actionPerformed(java.awt.event.ActionEvent evt) {
544                    toolbarPreferencesButtonActionPerformed(evt);
545                }
546            });
547            toolsMenu.add(preferencesMenuItem);
548            menuBar.add(toolsMenu);
549    
550    
551            windowMenu.setText(getResourceConverter().getString("workbench.menu.windows","Windows"));
552    
553            cascadeMenuItem = new javax.swing.JMenuItem();
554            cascadeMenuItem.setText(getResourceConverter().getString("workbench.menu.cascadeWindows","Cascade Windows"));
555            cascadeMenuItem.addActionListener(new java.awt.event.ActionListener() {
556                public void actionPerformed(java.awt.event.ActionEvent evt) {
557                    cascadeMenuItemActionPerformed(evt);
558                }
559            });
560    
561            tileMenuItem = new javax.swing.JMenuItem();
562            tileMenuItem.setText(getResourceConverter().getString("workbench.menu.tileWindows","Tile Windows"));
563            tileMenuItem.addActionListener(new java.awt.event.ActionListener() {
564                public void actionPerformed(java.awt.event.ActionEvent evt) {
565                    tileMenuItemActionPerformed(evt);
566                }
567            });
568    
569            closeAllMenuItem = new javax.swing.JMenuItem();
570            closeAllMenuItem.setText(getResourceConverter().getString("workbench.menu.closeAll","Close All"));
571            closeAllMenuItem.addActionListener(new java.awt.event.ActionListener() {
572                public void actionPerformed(java.awt.event.ActionEvent evt) {
573                    closeAllMenuItemActionPerformed(evt);
574                }
575            });
576    
577            minimizeMenuItem = new javax.swing.JMenuItem();
578            minimizeMenuItem.setText(getResourceConverter().getString("workbench.menu.minimizeAll","Minimize All"));
579            minimizeMenuItem.addActionListener(new java.awt.event.ActionListener() {
580                public void actionPerformed(java.awt.event.ActionEvent evt) {
581                    minimizeMenuItemActionPerformed(evt);
582                }
583            });
584    
585            maximizeMenuItem = new javax.swing.JMenuItem();
586            maximizeMenuItem.setText(getResourceConverter().getString("workbench.menu.maximizeAll","Maximize All"));
587            maximizeMenuItem.addActionListener(new java.awt.event.ActionListener() {
588                public void actionPerformed(java.awt.event.ActionEvent evt) {
589                    maximizeMenuItemActionPerformed(evt);
590                }
591            });
592    
593            menuBar.add(windowMenu);
594    
595            aboutMenuItem.setText(getResourceConverter().getString("workbench.menu.about","About"));
596            aboutMenuItem.addActionListener(new java.awt.event.ActionListener() {
597                public void actionPerformed(java.awt.event.ActionEvent evt) {
598                    aboutMenuItemActionPerformed(evt);
599                }
600            });
601    
602            helpMenu.add(aboutMenuItem);
603    
604            helpMenu.setText(getResourceConverter().getString("workbench.menu.help","Help"));
605            menuBar.add(helpMenu);
606    
607            setJMenuBar(menuBar);
608    
609            pack();
610        }
611    
612        /**
613         * this method loads any available menubar plugins based on
614         *
615         */
616        private void loadMenubarPlugins() {
617            // render any plugins
618            InputStream pluginStream = null;
619            try {
620                Properties props = new Properties();
621                pluginStream =
622                    getClass().getResourceAsStream("/workbench_plugins.properties");
623                if (pluginStream != null) {
624                    props.load(pluginStream);
625                    for (Object key : props.keySet()) {
626                        String keystr = (String)key;
627                        if (keystr.startsWith("workbench.menu-plugin")) {
628                            String val = props.getProperty(keystr);
629                            WorkbenchMenubarPlugin plugin =
630                                (WorkbenchMenubarPlugin)Class.forName(val).newInstance();
631                            plugin.setWorkbench(this);
632                            plugin.addItemsToMenubar(menuBar);
633                        }
634                    }
635                }
636            } catch (Exception e) {
637                e.printStackTrace();
638            } finally {
639                try {
640                    if (pluginStream != null) {
641                        pluginStream.close();
642                    }
643                } catch (Exception e) {
644                }
645            }
646        }
647    
648    
649        /**
650         * @return the workbenchResourceBundle
651         */
652        public ResourceBundle getWorkbenchResourceBundle() {
653            return workbenchResourceBundle;
654        }
655    
656        /**
657         * @return the resources
658         */
659        public ResourceBundle getGUIResourceBundle() {
660            return guiResourceBundle;
661        }
662    
663        /**
664         * @return the resourceConverter
665         */
666        public I18n getResourceConverter() {
667            return resourceConverter;
668        }
669    
670        private void tileMenuItemActionPerformed(java.awt.event.ActionEvent evt) {
671            Dimension dsize = desktopPane.getSize();
672            int desktopW = (int) dsize.getWidth();
673            int desktopH = (int) dsize.getHeight();
674            int darea =  (int) (desktopW * desktopH);
675    
676            double eacharea = darea / (schemaWindowMap.size() + mdxWindows.size());
677            int wh = (int) Math.sqrt(eacharea);
678    
679            Iterator []its = new Iterator[2];
680    
681            its[0] = schemaWindowMap.keySet().iterator();   // keys = schemaframes
682            its[1] = mdxWindows.iterator();
683    
684            JInternalFrame sf = null;
685            int x = 0, y = 0;
686    
687            try {
688                for (int i = 0; i < its.length; i++) {
689                    Iterator it = its[i];
690                    while (it.hasNext()) {
691                        sf = (JInternalFrame) it.next();
692                        if (sf != null) {
693                            if (sf.isIcon()) {
694                                //sf.setIcon(false);
695                            } else {
696                                sf.setMaximum(false);
697                                sf.moveToFront();
698                                if ((x >= desktopW) || (((desktopW - x) * wh) < (eacharea / 2))) {
699                                    // move to next row of windows
700                                    y += wh;
701                                    x = 0;
702                                }
703                                int sfwidth  = ((x + wh) < desktopW ? wh : desktopW - x);
704                                int sfheight = ((y + wh) < desktopH ? wh : desktopH - y);
705                                sf.setBounds(x, y, sfwidth, sfheight);
706                                x += sfwidth;
707                            }
708                        }
709                    }
710                }
711            } catch (Exception ex) {
712                LOGGER.error("tileMenuItemActionPerformed", ex);
713                //do nothing
714            }
715        }
716        // cascade all the indows open in schema workbench
717        private void cascadeMenuItemActionPerformed(java.awt.event.ActionEvent evt) {
718            Iterator []its = new Iterator[2];
719    
720            its[0] = schemaWindowMap.keySet().iterator();   // keys = schemaframes
721            its[1] = mdxWindows.iterator();
722            int sfi = 1;
723            JInternalFrame sf = null;
724    
725            try {
726                for (int i = 0; i < its.length; i++) {
727                    Iterator it = its[i];
728                    while (it.hasNext()) {
729                        sf = (JInternalFrame) it.next();
730                        if (sf != null) {
731                            if (sf.isIcon()) {
732                                //sf.setIcon(false);
733                            } else {
734                                sf.setMaximum(false);
735                                sf.setLocation(30 * sfi, 30 * sfi);
736                                sf.moveToFront();
737                                sf.setSelected(true);
738                                sfi++;
739                            }
740                        }
741                    }
742                }
743            } catch (Exception ex) {
744                LOGGER.error("cascadeMenuItemActionPerformed", ex);
745                //do nothing
746            }
747        }
748    
749        // close all the windows open in schema workbench
750        private void closeAllMenuItemActionPerformed(java.awt.event.ActionEvent evt) {
751            closeAllSchemaFrames(false);
752        }
753    
754        private void closeAllSchemaFrames(boolean exitAfterClose) {
755            Object [][] its = new Object[2][];  // initialize row dimension
756            its[0] = schemaWindowMap.keySet().toArray();   // keys = schemaframes
757            its[1] = mdxWindows.toArray();
758            JInternalFrame sf = null;
759    
760            try {
761                for (int i = 0; i < its.length; i++) {
762                    for (int j = 0; j < its[i].length; j++) {
763                        sf = (JInternalFrame) its[i][j];
764                        if (sf != null) {
765                            if (sf.getContentPane().getComponent(0) instanceof SchemaExplorer) {
766                                SchemaExplorer se = (SchemaExplorer) sf.getContentPane().getComponent(0);
767                                sf.setSelected(true);
768                                int response = confirmFrameClose(sf, se);
769                                if (response == 2) {    // cancel
770                                    return;
771                                }
772                                if (response == 3) {    // not dirty
773                                    sf.setClosed(true);
774                                }
775                            }
776                        }
777                    }
778                }
779                // exit Schema Workbench if no files are open
780                if (((schemaWindowMap.keySet().size()) == 0) && exitAfterClose) {
781                    System.exit(0);
782                }
783            } catch (Exception ex) {
784                LOGGER.error("closeAllSchemaFrames", ex);
785            }
786        }
787    
788        private int confirmFrameClose(JInternalFrame schemaFrame, SchemaExplorer se) {
789            if (se.isDirty()) {
790                JMenuItem schemaMenuItem = (JMenuItem) schemaWindowMap.get(desktopPane.getSelectedFrame());
791                int answer =
792                    JOptionPane.showConfirmDialog(
793                        null,
794                        getResourceConverter().getFormattedString(
795                            "workbench.saveSchemaOnClose.alert",
796                            "Save changes to {0}?",
797                            new String[] { se.getSchemaFile().toString() }),
798                        getResourceConverter().getString("workbench.saveSchemaOnClose.title","Schema"),
799                        JOptionPane.YES_NO_CANCEL_OPTION);
800                switch (answer) { // yes=0; no=1; cancel=2
801                case 0:
802                    saveMenuItemActionPerformed(null);
803                    schemaWindowMap.remove(schemaFrame); //schemaWindowMap.remove(se.getSchemaFile());
804                    updateMDXCatalogList();
805                    schemaFrame.dispose();
806                    windowMenu.remove(schemaMenuItem);  // follow this by removing file from schemaWindowMap
807                    break;
808                case 1:
809                    schemaFrame.dispose();
810                    schemaWindowMap.remove(schemaFrame);
811                    windowMenu.remove(schemaMenuItem);
812                    break;
813                case 2:
814                    try {
815                        schemaFrame.setClosed(false);
816                        schemaFrame.show();
817                    } catch (Exception ex) {
818                        LOGGER.error(ex);
819                    }
820                }
821                return answer;
822            }
823            return 3;
824        }
825    
826        private void minimizeMenuItemActionPerformed(java.awt.event.ActionEvent evt) {
827            Iterator []its = new Iterator[2];
828    
829            its[0] = schemaWindowMap.keySet().iterator();   // values = schemaframes
830            its[1] = mdxWindows.iterator();
831            JInternalFrame sf;
832    
833            try {
834                for (int i = 0; i < its.length; i++) {
835                    Iterator it = its[i];
836                    while (it.hasNext()) {
837                        sf = (JInternalFrame) it.next();
838                        if (sf != null) {
839                            if (sf.isIcon()) {
840                                //sf.setIcon(false);
841                            } else {
842                                sf.setIcon(true);
843                            }
844                        }
845                    }
846                }
847            } catch (Exception ex) {
848                LOGGER.error("minimizeMenuItemActionPerformed", ex);
849                //do nothing
850            }
851        }
852    
853        private void maximizeMenuItemActionPerformed(java.awt.event.ActionEvent evt) {
854            Iterator []its = new Iterator[2];
855    
856            its[0] = schemaWindowMap.keySet().iterator();   // values = schemaframes
857            its[1] = mdxWindows.iterator();
858            JInternalFrame sf;
859    
860            try {
861                for (int i = 0; i < its.length; i++) {
862                    Iterator it = its[i];
863                    while (it.hasNext()) {
864                        sf = (JInternalFrame) it.next();
865                        if (sf != null) {
866                            sf.setIcon(false);
867                            sf.setMaximum(true);
868                        }
869                    }
870                }
871            } catch (Exception ex) {
872                LOGGER.error("maximizeMenuItemActionPerformed", ex);
873                //do nothing
874            }
875        }
876    
877        private void aboutMenuItemActionPerformed(java.awt.event.ActionEvent evt) {
878            try {
879                JEditorPane jEditorPane = new JEditorPane(myClassLoader.getResource(resourceConverter.getGUIReference("version")).toString());
880                jEditorPane.setEditable(false);
881                JScrollPane jScrollPane = new JScrollPane(jEditorPane);
882                JPanel jPanel = new JPanel();
883                jPanel.setLayout(new java.awt.BorderLayout());
884                jPanel.add(jScrollPane, java.awt.BorderLayout.CENTER);
885    
886                JInternalFrame jf = new JInternalFrame();
887                jf.setTitle("About");
888                jf.getContentPane().add(jPanel);
889    
890                Dimension screenSize = this.getSize();
891                int aboutW = 400;
892                int aboutH = 300;
893                int width = (screenSize.width / 2) - (aboutW / 2);
894                int height = (screenSize.height / 2) - (aboutH / 2) - 100;
895                jf.setBounds(width, height, aboutW, aboutH);
896                jf.setClosable(true);
897    
898                desktopPane.add(jf);
899    
900                jf.setVisible(true);
901                jf.show();
902            } catch (Exception ex) {
903                LOGGER.error("aboutMenuItemActionPerformed", ex);
904            }
905    
906        }
907        private void newJDBCExplorerMenuItemActionPerformed(java.awt.event.ActionEvent evt) {
908            try {
909                if (jdbcDriverClassName == null || jdbcDriverClassName.trim().length() == 0 ||
910                        jdbcConnectionUrl == null || jdbcConnectionUrl.trim().length() == 0) {
911                    throw new Exception("Driver=" + this.jdbcDriverClassName + "\nConnection Url=" + this.jdbcConnectionUrl);
912                }
913    
914                JInternalFrame jf = new JInternalFrame();
915                jf.setTitle(getResourceConverter().getFormattedString("workbench.new.JDBCExplorer.title",
916                        "JDBC Explorer - {0}",
917                        new String[] { jdbcConnectionUrl }));
918                //jf.setTitle("JDBC Explorer - " + this.jdbcConnectionUrl);
919    
920                Class.forName(jdbcDriverClassName);
921    
922                java.sql.Connection conn = null;
923    
924                if (jdbcUsername != null && jdbcUsername.length() > 0 &&
925                    jdbcPassword != null && jdbcPassword.length() > 0) {
926                    conn = java.sql.DriverManager.getConnection(jdbcConnectionUrl, jdbcUsername, jdbcPassword);
927                } else {
928    
929                    conn = java.sql.DriverManager.getConnection(jdbcConnectionUrl);
930                }
931    
932                JDBCExplorer jdbce = new JDBCExplorer(conn);
933    
934                jf.getContentPane().add(jdbce);
935                jf.setBounds(0, 0, 500, 480);
936                jf.setClosable(true);
937                jf.setIconifiable(true);
938                jf.setMaximizable(true);
939                jf.setResizable(true);
940                jf.setVisible(true);
941    
942                desktopPane.add(jf);
943    
944                jf.show();
945            } catch (Exception ex) {
946                JOptionPane.showMessageDialog(this,
947                        getResourceConverter().getFormattedString("workbench.new.JDBCExplorer.exception",
948                                "Database connection not successful.\n{0}",
949                                new String[] { ex.getLocalizedMessage() }),
950                                getResourceConverter().getString("workbench.new.JDBCExplorer.exception.title", "Database Connection Error") , JOptionPane.ERROR_MESSAGE);
951                LOGGER.error("newJDBCExplorerMenuItemActionPerformed", ex);
952            }
953        }
954    
955        private void toolbarPreferencesButtonActionPerformed(java.awt.event.ActionEvent evt) {
956            PreferencesDialog pd = new PreferencesDialog(this, true);
957            pd.setJDBCConnectionUrl(jdbcConnectionUrl);
958            pd.setJDBCDriverClassName(jdbcDriverClassName);
959            pd.setJDBCUsername(jdbcUsername);
960            pd.setJDBCPassword(jdbcPassword);
961    
962            pd.show();
963    
964            if (pd.accepted()) {
965                jdbcConnectionUrl = pd.getJDBCConnectionUrl();
966                jdbcDriverClassName = pd.getJDBCDriverClassName();
967                jdbcUsername = pd.getJDBCUsername();
968                jdbcPassword = pd.getJDBCPassword();
969    
970                workbenchProperties.setProperty("jdbcDriverClassName", jdbcDriverClassName);
971                workbenchProperties.setProperty("jdbcConnectionUrl", jdbcConnectionUrl);
972                workbenchProperties.setProperty("jdbcUsername", jdbcUsername);
973                workbenchProperties.setProperty("jdbcPassword", jdbcPassword);
974            }
975        }
976    
977    
978        private void newSchemaMenuItemActionPerformed(java.awt.event.ActionEvent evt) {
979            MondrianProperties.instance();
980            /* user's default directory. This default depends on the operating system.
981             * It is typically the "My Documents" folder on Windows, and the
982             * user's home directory on Unix.
983             */
984            File defaultDir = FileSystemView.getFileSystemView().getDefaultDirectory();
985            File outputFile;
986            do  {
987                outputFile = new File(defaultDir, "Schema" + newSchema++ + ".xml");
988            } while (outputFile.exists());
989    
990            openSchemaFrame(outputFile, true);
991        }
992    
993        private void newQueryMenuItemActionPerformed(java.awt.event.ActionEvent evt) {
994    
995            JMenuItem schemaMenuItem = (JMenuItem) schemaWindowMap.get(desktopPane.getSelectedFrame());
996    
997            final JInternalFrame jf = new JInternalFrame();
998            jf.setTitle(getResourceConverter().getString("workbench.new.MDXQuery.title", "MDX Query"));
999            QueryPanel qp = new QueryPanel(this);
1000    
1001            jf.getContentPane().add(qp);
1002            jf.setBounds(0, 0, 500, 480);
1003            jf.setClosable(true);
1004            jf.setIconifiable(true);
1005            jf.setMaximizable(true);
1006            jf.setResizable(true);
1007            jf.setVisible(true);
1008    
1009            desktopPane.add(jf);
1010            jf.show();
1011            try {
1012                jf.setSelected(true);
1013            } catch (Exception ex) {
1014                // do nothing
1015                LOGGER.error("newQueryMenuItemActionPerformed.setSelected", ex);
1016            }
1017    
1018            // add the mdx frame to this set of mdx frames for cascading method
1019            mdxWindows.add(jf);
1020    
1021            // create mdx menu item
1022            final javax.swing.JMenuItem queryMenuItem = new javax.swing.JMenuItem();
1023            queryMenuItem.setText(getResourceConverter().getFormattedString("workbench.new.MDXQuery.menuitem",
1024                    "{0} MDX",
1025                    new String[] { Integer.toString(windowMenuMapIndex) }));
1026            queryMenuItem.addActionListener(new java.awt.event.ActionListener() {
1027                public void actionPerformed(java.awt.event.ActionEvent evt) {
1028                    try {
1029                        if (jf.isIcon()) {
1030                            jf.setIcon(false);
1031                        } else {
1032                            jf.setSelected(true);
1033                        }
1034                    } catch (Exception ex) {
1035                        LOGGER.error("queryMenuItem", ex);
1036                    }
1037                }
1038            });
1039    
1040            // disable mdx frame close operation to provide our handler
1041            // to remove frame object from mdxframeset before closing
1042            jf.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
1043    
1044            jf.addInternalFrameListener(new InternalFrameAdapter() {
1045                public void internalFrameClosing(InternalFrameEvent e) {
1046                    mdxWindows.remove(jf);
1047                    jf.dispose();
1048                    windowMenu.remove(queryMenuItem);  // follow this by removing file from schemaWindowMap
1049                    return;
1050                }
1051            });
1052    
1053            windowMenu.add(queryMenuItem,-1);
1054            windowMenu.add(jSeparator3,-1);
1055            windowMenu.add(cascadeMenuItem,-1);
1056            windowMenu.add(tileMenuItem,-1);
1057            windowMenu.add(minimizeMenuItem, -1);
1058            windowMenu.add(maximizeMenuItem, -1);
1059            windowMenu.add(closeAllMenuItem,-1);
1060    
1061            qp.setMenuItem(queryMenuItem);
1062            qp.setSchemaWindowMap(schemaWindowMap);
1063            qp.setWindowMenuIndex(windowMenuMapIndex++);
1064    
1065            if (schemaMenuItem != null) {
1066                qp.initConnection(schemaMenuItem.getText());
1067            } else {
1068                JOptionPane.showMessageDialog(this,getResourceConverter().getString("workbench.new.MDXQuery.no.selection", "No Mondrian connection. Select a Schema to connect."),
1069                        getResourceConverter().getString("workbench.new.MDXQuery.no.selection.title", "Alert"), JOptionPane.WARNING_MESSAGE);
1070            }
1071        }
1072    
1073        // inform all opened mdx query windows about the list of opened schema files
1074        private void updateMDXCatalogList() {
1075            Iterator it = mdxWindows.iterator();
1076            while (it.hasNext()) {
1077                JInternalFrame elem = (JInternalFrame)  it.next();
1078                QueryPanel qp = (QueryPanel) elem.getContentPane().getComponent(0);
1079                qp.setSchemaWindowMap(schemaWindowMap);
1080            }
1081        }
1082    
1083        /**
1084         * returns the currently selected schema explorer object
1085         *
1086         * @return current schema explorer object
1087         */
1088        public SchemaExplorer getCurrentSchemaExplorer() {
1089            JInternalFrame jf = desktopPane.getSelectedFrame();
1090            if (jf != null &&
1091                jf.getContentPane().getComponentCount() > 0 &&
1092                jf.getContentPane().getComponent(0) instanceof SchemaExplorer) {
1093                return (SchemaExplorer) jf.getContentPane().getComponent(0);
1094            }
1095            return null;
1096        }
1097    
1098        private void saveAsMenuItemActionPerformed(java.awt.event.ActionEvent evt) {
1099            JInternalFrame jf = desktopPane.getSelectedFrame();
1100    
1101            if (jf.getContentPane().getComponent(0) instanceof SchemaExplorer) {
1102                SchemaExplorer se = (SchemaExplorer) jf.getContentPane().getComponent(0);
1103                java.io.File schemaFile = se.getSchemaFile();
1104                java.io.File oldSchemaFile = schemaFile;
1105                java.io.File suggSchemaFile = new File(schemaFile, se.getSchema().name.trim() + ".xml");
1106                MondrianGuiDef.Schema schema = se.getSchema();
1107                JFileChooser jfc = new JFileChooser();
1108                MondrianProperties.instance();
1109    
1110                jfc.setSelectedFile(suggSchemaFile);
1111    
1112                if (jfc.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) {
1113                    try {
1114                        schemaFile = jfc.getSelectedFile();
1115                        if (!oldSchemaFile.equals(schemaFile) && schemaFile.exists()) {  //new file already exists, check for overwrite
1116                            int answer = JOptionPane.showConfirmDialog(null,
1117                                    getResourceConverter().getFormattedString("workbench.saveAs.schema.confirm",
1118                                            "{0} schema file already exists. Do you want to replace it?",
1119                                            new String[] { schemaFile.getAbsolutePath() }),
1120                                            getResourceConverter().getString("workbench.saveAs.schema.confirm.title", "Save As"), JOptionPane.YES_NO_OPTION);
1121                            if (answer == 1) { //  no=1 ; yes=0
1122                                return;
1123                            }
1124                        }
1125    
1126                        if (se.isNewFile() && !oldSchemaFile.equals(schemaFile)) {
1127                            oldSchemaFile.delete();
1128                        }
1129    
1130                        if (se.isNewFile()) {
1131                            se.setNewFile(false);
1132                        }
1133                        se.setDirty(false);
1134                        se.setDirtyFlag(false);
1135    
1136                        XMLOutput out = new XMLOutput(new java.io.FileWriter(jfc.getSelectedFile()));
1137                        schema.displayXML(out);
1138                        se.setSchemaFile(schemaFile);
1139                        se.setTitle();  //sets title of iframe
1140                        setLastUsed(jfc.getSelectedFile().getName(), jfc.getSelectedFile().toURI().toURL().toString());
1141    
1142                        // update menu item with new file name, then update catalog list for mdx queries
1143                        JMenuItem sMenuItem = (JMenuItem) schemaWindowMap.get(jf);
1144                        String mtexttokens[] = sMenuItem.getText().split(" ");
1145                        sMenuItem.setText(mtexttokens[0] + " " + se.getSchemaFile().getName());
1146                        updateMDXCatalogList(); // schema menu item updated, now update mdx query windows with updated catallog list
1147                    } catch (Exception ex) {
1148                        LOGGER.error(ex);
1149                    }
1150                }
1151            }
1152        }
1153    
1154        private void viewXMLMenuItemActionPerformed(java.awt.event.ActionEvent evt) {
1155            JInternalFrame jf = desktopPane.getSelectedFrame();
1156            boolean oldValue = viewXMLMenuItem.getState();
1157            if (jf != null && jf.getContentPane().getComponent(0) instanceof SchemaExplorer) {
1158                SchemaExplorer se = (SchemaExplorer) jf.getContentPane().getComponent(0);
1159                // call schema explorer's view xml event and update the workbench's view menu accordingly'
1160                ((JCheckBoxMenuItem) evt.getSource()).setSelected(se.editMode(evt));
1161                return;
1162            }
1163            viewXMLMenuItem.setSelected(! oldValue);
1164        }
1165    
1166        public void saveMenuItemActionPerformed(java.awt.event.ActionEvent evt) {
1167            JInternalFrame jf = desktopPane.getSelectedFrame();
1168    
1169            // Don't save if nothing there
1170            if (jf == null || jf.getContentPane() == null) {
1171                return;
1172            }
1173    
1174            if (jf.getContentPane().getComponent(0) instanceof SchemaExplorer) {
1175                SchemaExplorer se = (SchemaExplorer) jf.getContentPane().getComponent(0);
1176    
1177                java.io.File schemaFile = se.getSchemaFile();
1178    
1179                if (se.isNewFile()) {
1180                    saveAsMenuItemActionPerformed(evt);
1181                    return;
1182                }
1183    
1184                se.setDirty(false);
1185                se.setDirtyFlag(false);
1186                se.setTitle();  //sets title of iframe
1187    
1188                MondrianGuiDef.Schema schema = se.getSchema();
1189                MondrianProperties.instance();
1190                try {
1191                    XMLOutput out = new XMLOutput(new FileWriter(schemaFile));
1192                    schema.displayXML(out);
1193                    setLastUsed(schemaFile.getName(), schemaFile.toURI().toURL().toString());
1194                } catch (Exception ex) {
1195                    LOGGER.error("saveMenuItemActionPerformed", ex);
1196                }
1197            }
1198        }
1199    
1200        /**
1201         * Set last used in properties file
1202         *
1203         * @param name
1204         * @param url
1205         */
1206        private void setLastUsed(String name, String url) {
1207            int match = 4;
1208            String luName = null;
1209            String propname = null;
1210            String lastUsed = "lastUsed";
1211            String lastUsedUrl = "lastUsedUrl";
1212            for (int i = 1; i <= 4; i++) {
1213                propname = lastUsed + i;
1214                luName = workbenchProperties.getProperty(propname) ;
1215    
1216                if (luName != null && luName.equals(name)) {
1217                    match = i;
1218                    break;
1219                }
1220            }
1221    
1222            for (int i = match; i > 1; i--) {
1223                if (workbenchProperties.getProperty(lastUsed + (i - 1)) != null) {
1224                    workbenchProperties.setProperty(lastUsed + i, workbenchProperties.getProperty(lastUsed + (i - 1)));
1225                    workbenchProperties.setProperty(lastUsedUrl + i, workbenchProperties.getProperty(lastUsedUrl + (i - 1)));
1226                }
1227            }
1228    
1229            workbenchProperties.setProperty(LAST_USED1, name);
1230            workbenchProperties.setProperty(LAST_USED1_URL, url);
1231            updateLastUsedMenu();
1232            storeWorkbenchProperties();
1233        }
1234    
1235        private void updateLastUsedMenu() {
1236            if (workbenchProperties.getProperty(LAST_USED1) == null) {
1237                jSeparator2.setVisible(false);
1238            } else {
1239                jSeparator2.setVisible(true); }
1240    
1241            if (workbenchProperties.getProperty(LAST_USED1) != null) {
1242                lastUsed1MenuItem.setVisible(true);
1243            } else {
1244                lastUsed1MenuItem.setVisible(false);
1245            }
1246            if (workbenchProperties.getProperty(LAST_USED2) != null) {
1247                lastUsed2MenuItem.setVisible(true);
1248            } else {
1249                lastUsed2MenuItem.setVisible(false);
1250            }
1251            if (workbenchProperties.getProperty(LAST_USED3) != null) {
1252                lastUsed3MenuItem.setVisible(true);
1253            } else {
1254                lastUsed3MenuItem.setVisible(false);
1255            }
1256            if (workbenchProperties.getProperty(LAST_USED4) != null) {
1257                lastUsed4MenuItem.setVisible(true);
1258            } else {
1259                lastUsed4MenuItem.setVisible(false);
1260            }
1261    
1262            lastUsed1MenuItem.setText(workbenchProperties.getProperty(LAST_USED1));
1263            lastUsed2MenuItem.setText(workbenchProperties.getProperty(LAST_USED2));
1264            lastUsed3MenuItem.setText(workbenchProperties.getProperty(LAST_USED3));
1265            lastUsed4MenuItem.setText(workbenchProperties.getProperty(LAST_USED4));
1266        }
1267    
1268        private void lastUsed1MenuItemActionPerformed(java.awt.event.ActionEvent evt) {
1269            try {
1270                openSchemaFrame(new File(new URI(workbenchProperties.getProperty(LAST_USED1_URL))), false);
1271            } catch (Exception e) //catch (URISyntaxException e)
1272            {
1273                LOGGER.error("lastUsed1MenuItemActionPerformed", e);
1274            }
1275        }
1276    
1277        private void lastUsed2MenuItemActionPerformed(java.awt.event.ActionEvent evt) {
1278            try {
1279                openSchemaFrame(new File(new URI(workbenchProperties.getProperty(LAST_USED2_URL))), false);
1280                setLastUsed(workbenchProperties.getProperty(LAST_USED2), workbenchProperties.getProperty(LAST_USED2_URL));
1281            } catch (URISyntaxException e) {
1282                LOGGER.error("lastUsed2MenuItemActionPerformed", e);
1283            }
1284        }
1285    
1286        private void lastUsed3MenuItemActionPerformed(java.awt.event.ActionEvent evt) {
1287            try {
1288                openSchemaFrame(new File(new URI(workbenchProperties.getProperty(LAST_USED3_URL))), false);
1289                setLastUsed(workbenchProperties.getProperty(LAST_USED3), workbenchProperties.getProperty(LAST_USED3_URL));
1290            } catch (URISyntaxException e) {
1291                LOGGER.error("lastUsed3MenuItemActionPerformed", e);
1292            }
1293        }
1294    
1295        private void lastUsed4MenuItemActionPerformed(java.awt.event.ActionEvent evt) {
1296            try {
1297                openSchemaFrame(new File(new URI(workbenchProperties.getProperty(LAST_USED4_URL))), false);
1298                setLastUsed(workbenchProperties.getProperty(LAST_USED4), workbenchProperties.getProperty(LAST_USED4_URL));
1299            } catch (URISyntaxException e) {
1300                LOGGER.error("lastUsed4MenuItemActionPerformed", e);
1301            }
1302        }
1303    
1304        /**
1305         *
1306         * @param file
1307         */
1308        private void openSchemaFrame(File file, boolean newFile) {
1309            try {
1310    
1311                if (! newFile) {
1312                    // check if file not already open
1313                    if (checkFileOpen(file)) {
1314                        return;
1315                    }
1316                    // check if schema file exists
1317                    if (! file.exists()) {
1318                        JOptionPane.showMessageDialog(this,
1319                                getResourceConverter().getFormattedString("workbench.open.schema.not.found",
1320                                        "{0} File not found.",
1321                                        new String[] { file.getAbsolutePath() }),
1322                                        getResourceConverter().getString("workbench.open.schema.not.found.title", "Alert"), JOptionPane.WARNING_MESSAGE);
1323                        return;
1324                    }
1325                    // check if file is writable
1326                    if (! file.canWrite()) {
1327                        JOptionPane.showMessageDialog(this,
1328                                getResourceConverter().getFormattedString("workbench.open.schema.not.writeable",
1329                                        "{0} is not writeable.",
1330                                        new String[] { file.getAbsolutePath() }),
1331                                        getResourceConverter().getString("workbench.open.schema.not.found.writeable", "Alert"), JOptionPane.WARNING_MESSAGE);
1332                        return;
1333                    }
1334                    // check if schema file is valid by initiating a mondrian connection
1335                    try {
1336                        // this connection parses the catalog file which if invalid will throw exception
1337                        String connectString = "Provider=mondrian;" +
1338                                "Jdbc=" + jdbcConnectionUrl + ";" +
1339                                    "Catalog=" + file.toURL().toString() + ";" +
1340                                    "JdbcDrivers=" + jdbcDriverClassName + ";";
1341    
1342                        if (jdbcUsername != null && jdbcUsername.length() > 0) {
1343                            connectString = connectString + "JdbcUser=" + jdbcUsername + ";";
1344                        }
1345                        if (jdbcPassword != null && jdbcPassword.length() > 0) {
1346                            connectString = connectString + "JdbcPassword=" + jdbcPassword + ";";
1347                        }
1348    
1349                        DriverManager.getConnection(connectString, null);
1350                    } catch (Exception ex) {
1351                        LOGGER.error("Exception : Schema file " + file.getAbsolutePath() + " is invalid." + ex.getMessage(), ex);
1352                    } catch (Error err) {
1353                        LOGGER.error("Error : Schema file " + file.getAbsolutePath() + " is invalid." + err.getMessage(), err);
1354                    }
1355                }
1356    
1357                final JInternalFrame schemaFrame = new JInternalFrame();
1358                schemaFrame.setTitle(getResourceConverter().getFormattedString("workbench.open.schema.title",
1359                        "Schema - {0}",
1360                        new String[] { file.getName() }));
1361                //schemaFrame.setTitle("Schema - " + file.getName());
1362    
1363                jdbcMetaData = new JDBCMetaData(this, jdbcDriverClassName, jdbcConnectionUrl, jdbcUsername, jdbcPassword);
1364    
1365                schemaFrame.getContentPane().add(new SchemaExplorer(this, file, jdbcMetaData, newFile, schemaFrame));
1366    
1367                String errorOpening = ((SchemaExplorer) schemaFrame.getContentPane().getComponent(0)).getErrMsg() ;
1368                if (errorOpening != null) {
1369                    JOptionPane.showMessageDialog(this,
1370                            getResourceConverter().getFormattedString("workbench.open.schema.error",
1371                                    "Error opening schema - {0}.",
1372                                    new String[] { errorOpening }),
1373                                    getResourceConverter().getString("workbench.open.schema.error.title", "Error"), JOptionPane.ERROR_MESSAGE);
1374                    schemaFrame.setClosed(true);
1375                    return;
1376                }
1377    
1378                schemaFrame.setBounds(0, 0, 1000, 650);
1379                schemaFrame.setClosable(true);
1380                schemaFrame.setIconifiable(true);
1381                schemaFrame.setMaximizable(true);
1382                schemaFrame.setResizable(true);
1383                schemaFrame.setVisible(true);
1384    
1385                desktopPane.add(schemaFrame, javax.swing.JLayeredPane.DEFAULT_LAYER);
1386                schemaFrame.show();
1387                schemaFrame.setMaximum(true);
1388    
1389                // display jdbc connection status warning, if connection is uncsuccessful
1390                if (jdbcMetaData.getErrMsg() != null) {
1391                    JOptionPane.showMessageDialog(this,
1392                            getResourceConverter().getFormattedString("workbench.open.schema.jdbc.error",
1393                                    "Database connection could not be done.\n{0}\nAll validations related to database will be ignored.",
1394                                    new String[] { jdbcMetaData.getErrMsg() }),
1395                                    getResourceConverter().getString("workbench.open.schema.jdbc.error.title", "Alert"), JOptionPane.WARNING_MESSAGE);
1396                }
1397    
1398                final javax.swing.JMenuItem schemaMenuItem = new javax.swing.JMenuItem();
1399                schemaMenuItem.setText(windowMenuMapIndex++ + " "  + file.getName());
1400                schemaMenuItem.addActionListener(new java.awt.event.ActionListener() {
1401                    public void actionPerformed(java.awt.event.ActionEvent evt) {
1402                        try {
1403                            if (schemaFrame.isIcon()) {
1404                                schemaFrame.setIcon(false);
1405                            } else {
1406                                schemaFrame.setSelected(true);
1407                            }
1408                        } catch (Exception ex) {
1409                            LOGGER.error("schemaMenuItem", ex);
1410                        }
1411                    }
1412                });
1413    
1414                windowMenu.add(schemaMenuItem,0);
1415                windowMenu.setEnabled(true);
1416    
1417                windowMenu.add(jSeparator3,-1);
1418                windowMenu.add(cascadeMenuItem,-1);
1419                windowMenu.add(tileMenuItem,-1);
1420                windowMenu.add(minimizeMenuItem, -1);
1421                windowMenu.add(maximizeMenuItem, -1);
1422                windowMenu.add(closeAllMenuItem,-1);
1423    
1424                // add the file details in menu map
1425                schemaWindowMap.put(schemaFrame, schemaMenuItem);
1426                updateMDXCatalogList();
1427    
1428                schemaFrame.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
1429    
1430                schemaFrame.addInternalFrameListener(new InternalFrameAdapter() {
1431                    public void internalFrameClosing(InternalFrameEvent e) {
1432                        if (schemaFrame.getContentPane().getComponent(0) instanceof SchemaExplorer) {
1433                            SchemaExplorer se = (SchemaExplorer) schemaFrame.getContentPane().getComponent(0);
1434                            int response = confirmFrameClose(schemaFrame, se);
1435                            if (response == 3) {    // not dirty
1436                                if (se.isNewFile()) {
1437                                    se.getSchemaFile().delete();
1438                                }
1439                                // default case for no save and not dirty
1440                                schemaWindowMap.remove(schemaFrame);
1441                                updateMDXCatalogList();
1442                                schemaFrame.dispose();
1443                                windowMenu.remove(schemaMenuItem);
1444                            }
1445                        }
1446                    }
1447                });
1448    
1449                schemaFrame.setFocusable(true);
1450                schemaFrame.addFocusListener(new FocusAdapter() {
1451                    public void focusGained(FocusEvent e) {
1452                        if (schemaFrame.getContentPane().getComponent(0) instanceof SchemaExplorer) {
1453                            SchemaExplorer se = (SchemaExplorer) schemaFrame.getContentPane().getComponent(0);
1454                            viewXMLMenuItem.setSelected(se.isEditModeXML());    // update view menu based on schemaframe who gained focus
1455                        }
1456                    }
1457    
1458                    public void focusLost(FocusEvent e) {
1459                        if (schemaFrame.getContentPane().getComponent(0) instanceof SchemaExplorer) {
1460                            SchemaExplorer se = (SchemaExplorer) schemaFrame.getContentPane().getComponent(0);
1461                            viewXMLMenuItem.setSelected(se.isEditModeXML());  // update view menu based on
1462                        }
1463                    }
1464    
1465                });
1466                viewXMLMenuItem.setSelected(false);
1467            } catch (Exception ex) {
1468                LOGGER.error("openSchemaFrame", ex);
1469            }
1470    
1471        }
1472        private void openMenuItemActionPerformed(java.awt.event.ActionEvent evt) {
1473            JFileChooser jfc = new JFileChooser();
1474            try {
1475                jfc.setFileSelectionMode(JFileChooser.FILES_ONLY) ;
1476                jfc.setFileFilter(new javax.swing.filechooser.FileFilter() {
1477                    public boolean accept(File pathname) {
1478                        return pathname.getName().toLowerCase().endsWith(".xml")
1479                        || pathname.isDirectory();
1480                    }
1481                    public String getDescription() {
1482                        return getResourceConverter().getString("workbench.open.schema.file.type", "Mondrian Schema files (*.xml)");
1483                    }
1484    
1485                });
1486    
1487                String lastUsed = workbenchProperties.getProperty(LAST_USED1_URL);
1488    
1489                if (lastUsed != null) {
1490                    jfc.setCurrentDirectory(new File(new URI(lastUsed)));
1491                }
1492            } catch (Exception ex) {
1493                LOGGER.error("Could not set file chooser", ex);
1494            }
1495            MondrianProperties.instance();
1496            if (jfc.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
1497                try {
1498                    setLastUsed(jfc.getSelectedFile().getName(), jfc.getSelectedFile().toURI().toURL().toString());
1499                } catch (MalformedURLException e) {
1500                    LOGGER.error(e);
1501                }
1502    
1503                openSchemaFrame(jfc.getSelectedFile(), false);
1504            }
1505        }
1506    
1507        // checks if file already open in schema explorer
1508        private boolean checkFileOpen(File file) {
1509    
1510            Iterator it = schemaWindowMap.keySet().iterator();  // keys=schemaframes
1511            while (it.hasNext()) {
1512                JInternalFrame elem = (JInternalFrame) it.next();
1513                File f = ((SchemaExplorer) elem.getContentPane().getComponent(0)).getSchemaFile();
1514                if (f.equals(file)) {
1515                    try {
1516                        elem.setSelected(true); // make the schema file active
1517                        return true;
1518                    } catch (Exception ex) {
1519                        schemaWindowMap.remove(elem); // remove file from map as schema frame does not exist
1520                        break;
1521                    }
1522                }
1523            }
1524            return false;
1525    
1526        }
1527    
1528    
1529        private void exitMenuItemActionPerformed(java.awt.event.ActionEvent evt) {
1530            storeWorkbenchProperties();
1531            closeAllSchemaFrames(true);
1532        }
1533    
1534        /**
1535         * parseArgs - parse arguments passed into Workbench.
1536         *
1537         * @param args the command line arguments
1538         *
1539         * Right now, it's very simple.  Just search through the list
1540         * of arguments.  If it begins with -f=, then the rest is a file name.
1541         * Ignore any others.  We can make this more complicated later if we
1542         * need to.
1543         */
1544        private void parseArgs(String args[]) {
1545            for (int argNum = 0; argNum < args.length; argNum++) {
1546                if (args[argNum].startsWith("-f=")) {
1547                    openFile = args[argNum].substring(3);
1548                }
1549            }
1550        }
1551    
1552        public String getTooltip(String titleName) {
1553            try {
1554                return getWorkbenchResourceBundle().getString(titleName);
1555            } catch (MissingResourceException e) {
1556                return getResourceConverter().getFormattedString("workbench.tooltip.error",
1557                        "No help available for {0}",
1558                        new String[] { titleName });
1559            }
1560        }
1561    
1562        /**
1563         * @param args the command line arguments
1564         */
1565        public static void main(String args[]) {
1566            try {
1567                Workbench w = new Workbench();
1568                w.parseArgs(args);
1569                w.setSize(800, 600);
1570                // if user specified a file to open, do so now.
1571                if (w.openFile != null) {
1572                    File f = new File(w.openFile);
1573                    if (f.canRead()) {
1574                        w.openSchemaFrame(f.getAbsoluteFile(), false); // parameter to indicate this is a new or existing catalog file
1575                    }
1576                }
1577                w.show();
1578            } catch (Throwable ex) {
1579                LOGGER.error("main", ex);
1580            }
1581        }
1582    
1583    // Variables declaration - do not modify
1584        private javax.swing.JButton toolbarSaveAsButton;
1585        private javax.swing.JMenuItem openMenuItem;
1586        private javax.swing.JMenuItem lastUsed1MenuItem;
1587        private javax.swing.JMenuItem lastUsed2MenuItem;
1588        private javax.swing.JMenuItem lastUsed3MenuItem;
1589        private javax.swing.JMenuItem lastUsed4MenuItem;
1590        private javax.swing.JMenu fileMenu;
1591        private javax.swing.JMenuItem newQueryMenuItem;
1592        private javax.swing.JMenuItem newQueryMenuItem2;
1593        private javax.swing.JPanel jPanel1;
1594        private javax.swing.JPanel jPanel2;
1595        private javax.swing.JButton toolbarOpenButton;
1596        private javax.swing.JButton toolbarNewButton;
1597        private javax.swing.JButton toolbarNewArrowButton;
1598        private javax.swing.JSeparator jSeparator1;
1599        private javax.swing.JSeparator jSeparator2;
1600        private javax.swing.JSeparator jSeparator3;
1601        private javax.swing.JSeparator jSeparator4;
1602        private javax.swing.JMenuItem cutMenuItem;
1603        private javax.swing.JMenuBar menuBar;
1604        private javax.swing.JMenuItem saveMenuItem;
1605        private javax.swing.JMenuItem newJDBCExplorerMenuItem;
1606        private javax.swing.JMenuItem newJDBCExplorerMenuItem2;
1607        private javax.swing.JCheckBoxMenuItem viewCubesMenuItem;
1608        private javax.swing.JButton toolbarSaveButton;
1609        private javax.swing.JMenuItem copyMenuItem;
1610        private javax.swing.JDesktopPane desktopPane;
1611        private javax.swing.JMenu viewMenu;
1612        private javax.swing.JMenu toolsMenu;
1613        private javax.swing.JMenu newMenu;
1614        private javax.swing.JMenuItem deleteMenuItem;
1615        private javax.swing.JMenuItem newSchemaMenuItem;
1616        private javax.swing.JMenuItem newSchemaMenuItem2;
1617        private javax.swing.JMenuItem exitMenuItem;
1618        private javax.swing.JButton toolbarPreferencesButton;
1619        private javax.swing.JCheckBoxMenuItem viewMeasuresMenuItem;
1620        private javax.swing.JMenu editMenu;
1621        private javax.swing.JMenuItem pasteMenuItem;
1622        private javax.swing.JMenuItem preferencesMenuItem;
1623        private javax.swing.JCheckBoxMenuItem viewDimensionsMenuItem;
1624        private javax.swing.JCheckBoxMenuItem viewXMLMenuItem;
1625        private javax.swing.JMenuItem saveAsMenuItem;
1626        private javax.swing.JToolBar jToolBar1;
1627        private javax.swing.JToolBar jToolBar2;
1628        private javax.swing.JPopupMenu toolbarNewPopupMenu;
1629        private javax.swing.JMenu windowMenu;
1630        private javax.swing.JMenu helpMenu;
1631        private javax.swing.JMenuItem aboutMenuItem;
1632        private javax.swing.JMenuItem cascadeMenuItem;
1633        private javax.swing.JMenuItem tileMenuItem;
1634        private javax.swing.JMenuItem minimizeMenuItem;
1635        private javax.swing.JMenuItem maximizeMenuItem;
1636        private javax.swing.JMenuItem closeAllMenuItem;
1637    // End of variables declaration
1638    
1639    
1640        /*
1641    class SchemaFrameComp implements Comparator {
1642      public int compare (Object o1, Object o2) {
1643        return o1 == o2;
1644      }
1645    }
1646         **/
1647    
1648        public javax.swing.JCheckBoxMenuItem getViewXMLMenuItem() {
1649            return viewXMLMenuItem; // used by schema framewhen it uses 'view xml' to update view xml menu item
1650        }
1651    
1652    
1653    }
1654    
1655    // End Workbench.java