001/*
002// This software is subject to the terms of the Eclipse Public License v1.0
003// Agreement, available at the following URL:
004// http://www.eclipse.org/legal/epl-v10.html.
005// You must accept the terms of that agreement to use this software.
006//
007// Copyright (C) 1999-2005 Julian Hyde
008// Copyright (C) 2005-2011 Pentaho and others
009// Copyright (C) 2006-2007 Cincom Systems, Inc.
010// Copyright (C) 2006-2007 JasperSoft
011// All Rights Reserved.
012*/
013package mondrian.gui;
014
015import mondrian.olap.DriverManager;
016import mondrian.olap.MondrianProperties;
017import mondrian.olap.Util;
018import mondrian.olap.Util.PropertyList;
019import mondrian.util.UnionIterator;
020
021import org.apache.commons.io.FileUtils;
022import org.apache.log4j.Logger;
023
024import org.eigenbase.xom.XMLOutput;
025
026import org.pentaho.di.core.Const;
027import org.pentaho.di.core.KettleClientEnvironment;
028import org.pentaho.di.core.database.DatabaseMeta;
029import org.pentaho.di.core.exception.KettleDatabaseException;
030import org.pentaho.di.core.exception.KettleException;
031import org.pentaho.ui.database.DatabaseConnectionDialog;
032import org.pentaho.ui.database.Messages;
033import org.pentaho.ui.database.event.DataHandler;
034import org.pentaho.ui.xul.*;
035import org.pentaho.ui.xul.containers.XulDialog;
036import org.pentaho.ui.xul.swing.SwingXulLoader;
037
038import java.awt.*;
039import java.awt.event.*;
040import java.io.*;
041import java.net.*;
042import java.util.*;
043import java.util.List;
044import javax.swing.*;
045import javax.swing.event.InternalFrameAdapter;
046import javax.swing.event.InternalFrameEvent;
047import javax.swing.filechooser.FileSystemView;
048import javax.swing.plaf.basic.BasicArrowButton;
049import javax.swing.text.DefaultEditorKit;
050import javax.swing.tree.TreePath;
051
052/**
053 * @author sean
054 */
055public class Workbench extends javax.swing.JFrame {
056
057    private static final long serialVersionUID = 1L;
058    static String WORKBENCH_USER_HOME_DIR;
059    static String WORKBENCH_CONFIG_FILE;
060    static String DB_META_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 =
071        "mondrian.gui.resources.workbenchInfo";
072    private static final String GUIResourceName = "mondrian.gui.resources.gui";
073    private static final String TextResourceName =
074        "mondrian.gui.resources.text";
075    private static final String FILTER_SCHEMA_LIST = "FILTER_SCHEMA_LIST";
076
077    private static final Logger LOGGER = Logger.getLogger(Workbench.class);
078
079    private String jdbcDriverClassName;
080    private String jdbcConnectionUrl;
081    private String jdbcUsername;
082    private String jdbcPassword;
083    private String jdbcSchema;
084    private boolean requireSchema;
085
086    private JdbcMetaData jdbcMetaData;
087
088    private final ClassLoader myClassLoader;
089
090    private Properties workbenchProperties;
091    private static ResourceBundle workbenchResourceBundle = null;
092
093    private static I18n resourceConverter = null;
094
095    private static int newSchema = 1;
096
097    private String openFile = null;
098
099    private Map<JInternalFrame, JMenuItem> schemaWindowMap =
100        new HashMap<JInternalFrame, JMenuItem>();
101
102    private final List<JInternalFrame> mdxWindows =
103        new ArrayList<JInternalFrame>();
104    private final List<JInternalFrame> jdbcWindows =
105        new ArrayList<JInternalFrame>();
106    private int windowMenuMapIndex = 1;
107
108    private static final String KETTLE_PLUGIN_BASE_FOLDERS = "kettle-plugins,"
109            + Const.getKettleDirectory() + Const.FILE_SEPARATOR + "plugins";
110    private XulDialog connectionDialog = null;
111    private DataHandler connectionDialogController = null;
112    private DatabaseMeta dbMeta = null;
113
114    /**
115     * Creates new form Workbench
116     */
117    public Workbench() {
118        myClassLoader = this.getClass().getClassLoader();
119
120        resourceConverter = getGlobalResourceConverter();
121
122        // Setting User home directory
123        WORKBENCH_USER_HOME_DIR =
124            System.getProperty("user.home")
125            + File.separator
126            + ".schemaWorkbench";
127        WORKBENCH_CONFIG_FILE =
128            WORKBENCH_USER_HOME_DIR + File.separator + "workbench.properties";
129        DB_META_CONFIG_FILE = WORKBENCH_USER_HOME_DIR + File.separator
130                + "databaseMeta.xml";
131
132        loadWorkbenchProperties();
133        loadDatabaseMeta();
134        initOptions();
135        initComponents();
136        loadMenubarPlugins();
137
138        ImageIcon icon = new javax.swing.ImageIcon(
139            myClassLoader.getResource(
140                getResourceConverter().getGUIReference("productIcon")));
141
142        this.setIconImage(icon.getImage());
143    }
144
145    public static I18n getGlobalResourceConverter() {
146        if (resourceConverter == null) {
147            ClassLoader currentClassLoader;
148
149            ResourceBundle localGuiResourceBundle;
150            ResourceBundle localTextResourceBundle;
151
152            currentClassLoader = Workbench.class.getClassLoader();
153
154            localGuiResourceBundle = ResourceBundle.getBundle(
155                GUIResourceName, Locale.getDefault(), currentClassLoader);
156            localTextResourceBundle = ResourceBundle.getBundle(
157                TextResourceName, Locale.getDefault(), currentClassLoader);
158
159            resourceConverter = new I18n(
160                localGuiResourceBundle, localTextResourceBundle);
161        }
162        return resourceConverter;
163    }
164
165    /**
166     * load properties
167     */
168    private void loadWorkbenchProperties() {
169        workbenchProperties = new Properties();
170        try {
171            workbenchResourceBundle = ResourceBundle.getBundle(
172                WorkbenchInfoResourceName, Locale.getDefault(),
173                    myClassLoader);
174            File f = new File(WORKBENCH_CONFIG_FILE);
175            if (f.exists()) {
176                workbenchProperties.load(new FileInputStream(f));
177            } else {
178                LOGGER.debug(WORKBENCH_CONFIG_FILE + " does not exist");
179            }
180        } catch (Exception e) {
181            // TODO deal with exception
182            LOGGER.error("loadWorkbenchProperties", e);
183        }
184    }
185
186    /**
187     * load database meta
188     */
189    public void loadDatabaseMeta() {
190        if (dbMeta == null) {
191            File file = new File(DB_META_CONFIG_FILE);
192            if (file.exists()) {
193                try {
194                    final String fileContents =
195                        FileUtils.readFileToString(file);
196                    if (!Util.isBlank(fileContents)) {
197                        dbMeta = getDbMeta(fileContents);
198                    }
199                } catch (Exception e) {
200                    LOGGER.error("loadDatabaseMeta", e);
201                }
202            }
203        }
204
205        if (dbMeta != null) {
206            syncToWorkspace(dbMeta);
207        }
208    }
209
210    /**
211     * returns the value of a workbench property
212     *
213     * @param key key to lookup
214     * @return the value
215     */
216    public String getWorkbenchProperty(String key) {
217        return workbenchProperties.getProperty(key);
218    }
219
220    /**
221     * set a workbench property.  Note that this does not save the property,
222     * a call to storeWorkbenchProperties is required.
223     *
224     * @param key   property key
225     * @param value property value
226     */
227    public void setWorkbenchProperty(String key, String value) {
228        workbenchProperties.setProperty(key, value);
229    }
230
231    /**
232     * save properties
233     */
234    public void storeWorkbenchProperties() {
235        //save properties to file
236        File dir = new File(WORKBENCH_USER_HOME_DIR);
237        try {
238            if (dir.exists()) {
239                if (!dir.isDirectory()) {
240                    JOptionPane.showMessageDialog(
241                        this,
242                        getResourceConverter().getFormattedString(
243                            "workbench.user.home.not.directory",
244                            "{0} is not a directory!\nPlease rename this file and retry to save configuration!",
245                            WORKBENCH_USER_HOME_DIR),
246                        "",
247                        JOptionPane.ERROR_MESSAGE);
248                    return;
249                }
250            } else {
251                dir.mkdirs();
252            }
253        } catch (Exception ex) {
254            LOGGER.error("storeWorkbenchProperties: mkdirs", ex);
255            JOptionPane.showMessageDialog(
256                this,
257                getResourceConverter().getFormattedString(
258                    "workbench.user.home.exception",
259                    "An error is occurred creating workbench configuration directory:\n{0}\nError is: {1}",
260                    WORKBENCH_USER_HOME_DIR,
261                    ex.getLocalizedMessage()),
262                "",
263                JOptionPane.ERROR_MESSAGE);
264            return;
265        }
266
267        OutputStream out = null;
268        try {
269            out = new FileOutputStream(
270                new File(
271                    WORKBENCH_CONFIG_FILE));
272            workbenchProperties.store(out, "Workbench configuration");
273        } catch (Exception e) {
274            LOGGER.error("storeWorkbenchProperties: store", e);
275            JOptionPane.showMessageDialog(
276                this,
277                getResourceConverter().getFormattedString(
278                    "workbench.save.configuration",
279                    "An error is occurred creating workbench configuration file:\n{0}\nError is: {1}",
280                    WORKBENCH_CONFIG_FILE,
281                    e.getLocalizedMessage()),
282                "",
283                JOptionPane.ERROR_MESSAGE);
284        } finally {
285            try {
286                out.close();
287            } catch (IOException eIO) {
288                LOGGER.error("storeWorkbenchProperties: out.close", eIO);
289            }
290        }
291    }
292
293    /**
294     * save database meta
295     */
296    public void storeDatabaseMeta() {
297        if (dbMeta != null) {
298            try {
299                File file = new File(DB_META_CONFIG_FILE);
300                PrintWriter pw = new PrintWriter(new FileWriter(file));
301                pw.println(dbMeta.getXML());
302                pw.close();
303            } catch (IOException e) {
304                LOGGER.error("storeDatabaseMeta", e);
305            }
306        }
307    }
308
309    /**
310     * Initialize the UI options
311     */
312    private void initOptions() {
313        requireSchema = "true".equals(getWorkbenchProperty("requireSchema"));
314    }
315
316    /**
317     * This method is called from within the constructor to
318     * initialize the form.
319     */
320    private void initComponents() {
321        desktopPane = new javax.swing.JDesktopPane();
322        jToolBar1 = new javax.swing.JToolBar();
323        jToolBar2 = new javax.swing.JToolBar();
324        toolbarNewPopupMenu = new JPopupMenu();
325        toolbarNewButton = new javax.swing.JButton();
326        toolbarOpenButton = new javax.swing.JButton();
327        toolbarSaveButton = new javax.swing.JButton();
328        toolbarSaveAsButton = new javax.swing.JButton();
329        jPanel1 = new javax.swing.JPanel();
330        jPanel2 = new javax.swing.JPanel();
331        toolbarPreferencesButton = new javax.swing.JButton();
332        requireSchemaCheckboxMenuItem = new javax.swing.JCheckBoxMenuItem();
333        menuBar = new javax.swing.JMenuBar();
334        fileMenu = new javax.swing.JMenu();
335        newMenu = new javax.swing.JMenu();
336        newSchemaMenuItem = new javax.swing.JMenuItem();
337        newQueryMenuItem = new javax.swing.JMenuItem();
338        newJDBCExplorerMenuItem = new javax.swing.JMenuItem();
339        newSchemaMenuItem2 = new javax.swing.JMenuItem();
340        newQueryMenuItem2 = new javax.swing.JMenuItem();
341        newJDBCExplorerMenuItem2 = new javax.swing.JMenuItem();
342        openMenuItem = new javax.swing.JMenuItem();
343        preferencesMenuItem = new javax.swing.JMenuItem();
344        lastUsed1MenuItem = new javax.swing.JMenuItem();
345        lastUsed2MenuItem = new javax.swing.JMenuItem();
346        lastUsed3MenuItem = new javax.swing.JMenuItem();
347        lastUsed4MenuItem = new javax.swing.JMenuItem();
348        saveMenuItem = new javax.swing.JMenuItem();
349        saveAsMenuItem = new javax.swing.JMenuItem();
350        jSeparator1 = new javax.swing.JSeparator();
351        jSeparator2 = new javax.swing.JSeparator();
352        jSeparator3 = new javax.swing.JSeparator();
353        exitMenuItem = new javax.swing.JMenuItem();
354        windowMenu = new javax.swing.JMenu();
355        helpMenu = new javax.swing.JMenu();
356        editMenu = new javax.swing.JMenu();
357        cutMenuItem =
358            new javax.swing.JMenuItem(new DefaultEditorKit.CutAction());
359        copyMenuItem =
360            new javax.swing.JMenuItem(new DefaultEditorKit.CopyAction());
361        pasteMenuItem =
362            new javax.swing.JMenuItem(new DefaultEditorKit.PasteAction());
363        deleteMenuItem =
364            new javax.swing.JMenuItem(
365                new AbstractAction(
366                    getResourceConverter().getString(
367                        "workbench.menu.delete", "Delete"))
368                {
369                    private static final long serialVersionUID = 1L;
370                    public void actionPerformed(ActionEvent e) {
371                        JInternalFrame jf = desktopPane.getSelectedFrame();
372                        if (jf != null && jf.getContentPane()
373                            .getComponent(0) instanceof SchemaExplorer)
374                        {
375                            SchemaExplorer se =
376                                (SchemaExplorer) jf.getContentPane()
377                                    .getComponent(0);
378                            TreePath tpath = se.tree.getSelectionPath();
379                            se.delete(tpath);
380                        }
381                    }
382                });
383        aboutMenuItem = new javax.swing.JMenuItem();
384        toolsMenu = new javax.swing.JMenu();
385        viewMenu = new javax.swing.JMenu();
386        viewXmlMenuItem = new javax.swing.JCheckBoxMenuItem();
387
388        setTitle(
389            getResourceConverter().getString(
390                "workbench.panel.title", "Schema Workbench"));
391        setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
392        addWindowListener(
393            new WindowAdapter() {
394                public void windowClosing(WindowEvent evt) {
395                    storeWorkbenchProperties();
396                    storeDatabaseMeta();
397                    closeAllSchemaFrames(true);
398                }
399            });
400
401        getContentPane().add(desktopPane, java.awt.BorderLayout.CENTER);
402
403
404        newSchemaMenuItem2.setText(
405            getResourceConverter().getString(
406                "workbench.menu.newSchema", "Schema"));
407        newSchemaMenuItem2.addActionListener(
408            new ActionListener() {
409                public void actionPerformed(ActionEvent evt) {
410                    newSchemaMenuItemActionPerformed(evt);
411                }
412            });
413
414        newQueryMenuItem2.setText(
415            getResourceConverter().getString(
416                "workbench.menu.newQuery", "MDX Query"));
417        newQueryMenuItem2.addActionListener(
418            new ActionListener() {
419                public void actionPerformed(ActionEvent evt) {
420                    newQueryMenuItemActionPerformed(evt);
421                }
422            });
423
424
425        newJDBCExplorerMenuItem2.setText(
426            getResourceConverter().getString(
427                "workbench.menu.newJDBC", "JDBC Explorer"));
428        newJDBCExplorerMenuItem2.addActionListener(
429            new ActionListener() {
430                public void actionPerformed(ActionEvent evt) {
431                    newJDBCExplorerMenuItemActionPerformed(evt);
432                }
433            });
434
435
436        toolbarNewPopupMenu.add(newSchemaMenuItem2);
437        toolbarNewPopupMenu.add(newQueryMenuItem2);
438        toolbarNewPopupMenu.add(newJDBCExplorerMenuItem2);
439
440
441        jPanel2.setLayout(new java.awt.BorderLayout());
442        jPanel2.setBorder(javax.swing.BorderFactory.createEtchedBorder());
443        jPanel2.setMaximumSize(new java.awt.Dimension(50, 28));
444
445        toolbarNewButton.setIcon(
446            new javax.swing.ImageIcon(
447                getClass().getResource(
448                    getResourceConverter().getGUIReference("new"))));
449        toolbarNewButton.setToolTipText(
450            getResourceConverter().getString(
451                "workbench.toolbar.new", "New"));
452        toolbarNewButton.setBorderPainted(false);
453        toolbarNewButton.addActionListener(
454            new ActionListener() {
455                public void actionPerformed(ActionEvent e) {
456                    toolbarNewPopupMenu.show(
457                        jPanel2, 0, jPanel2.getSize().height);
458                }
459            });
460
461        jToolBar2.setFloatable(false);
462        jToolBar2.add(toolbarNewButton);
463
464        jPanel2.add(jToolBar2, java.awt.BorderLayout.CENTER);
465
466        toolbarNewArrowButton = new BasicArrowButton(SwingConstants.SOUTH);
467        toolbarNewArrowButton.setToolTipText(
468            getResourceConverter().getString(
469                "workbench.toolbar.newArrow", "New"));
470        toolbarNewArrowButton.setBorderPainted(false);
471        toolbarNewArrowButton.addActionListener(
472            new ActionListener() {
473                public void actionPerformed(ActionEvent e) {
474                    toolbarNewPopupMenu.show(
475                        jPanel2, 0, jPanel2.getSize().height);
476                }
477            });
478
479        jPanel2.add(toolbarNewArrowButton, java.awt.BorderLayout.EAST);
480
481        jToolBar1.add(jPanel2, 0);
482
483
484        toolbarOpenButton.setIcon(
485            new javax.swing.ImageIcon(
486                getClass().getResource(
487                    getResourceConverter().getGUIReference("open"))));
488        toolbarOpenButton.setToolTipText(
489            getResourceConverter().getString(
490                "workbench.toolbar.open", "Open"));
491        toolbarOpenButton.addActionListener(
492            new ActionListener() {
493                public void actionPerformed(ActionEvent evt) {
494                    openMenuItemActionPerformed(evt);
495                }
496            });
497
498        jToolBar1.add(toolbarOpenButton);
499
500
501        toolbarSaveButton.setIcon(
502            new javax.swing.ImageIcon(
503                getClass().getResource(
504                    getResourceConverter().getGUIReference("save"))));
505        toolbarSaveButton.setToolTipText(
506            getResourceConverter().getString(
507                "workbench.toolbar.save", "Save"));
508        toolbarSaveButton.addActionListener(
509            new ActionListener() {
510                public void actionPerformed(ActionEvent evt) {
511                    saveMenuItemActionPerformed(evt);
512                }
513            });
514
515        jToolBar1.add(toolbarSaveButton);
516
517        toolbarSaveAsButton.setIcon(
518            new javax.swing.ImageIcon(
519                getClass().getResource(
520                    getResourceConverter().getGUIReference("saveAs"))));
521        toolbarSaveAsButton.setToolTipText(
522            getResourceConverter().getString(
523                "workbench.toolbar.saveAs", "Save As"));
524        toolbarSaveAsButton.addActionListener(
525            new ActionListener() {
526                public void actionPerformed(ActionEvent evt) {
527                    saveAsMenuItemActionPerformed(evt);
528                }
529            });
530
531        jToolBar1.add(toolbarSaveAsButton);
532
533        jPanel1.setMaximumSize(new java.awt.Dimension(8, 8));
534        jToolBar1.add(jPanel1);
535
536        toolbarPreferencesButton.setIcon(
537            new javax.swing.ImageIcon(
538                getClass().getResource(
539                    getResourceConverter().getGUIReference("preferences"))));
540        toolbarPreferencesButton.setToolTipText(
541            getResourceConverter().getString(
542                "workbench.toolbar.connection", "Connection"));
543        toolbarPreferencesButton.addActionListener(
544            new ActionListener() {
545                public void actionPerformed(ActionEvent evt) {
546                    connectionButtonActionPerformed(evt);
547                }
548            });
549
550        jToolBar1.add(toolbarPreferencesButton);
551
552
553        getContentPane().add(jToolBar1, java.awt.BorderLayout.NORTH);
554
555        fileMenu.setText(
556            getResourceConverter().getString(
557                "workbench.menu.file", "File"));
558        fileMenu.setMnemonic(KeyEvent.VK_F);
559        newMenu.setText(
560            getResourceConverter().getString(
561                "workbench.menu.new", "New"));
562
563        newSchemaMenuItem.setText(
564            getResourceConverter().getString(
565                "workbench.menu.newSchema", "Schema"));
566        newSchemaMenuItem.addActionListener(
567            new ActionListener() {
568                public void actionPerformed(ActionEvent evt) {
569                    newSchemaMenuItemActionPerformed(evt);
570                }
571            });
572
573        newMenu.add(newSchemaMenuItem);
574
575        newQueryMenuItem.setText(
576            getResourceConverter().getString(
577                "workbench.menu.newQuery", "MDX Query"));
578        newQueryMenuItem.addActionListener(
579            new ActionListener() {
580                public void actionPerformed(ActionEvent evt) {
581                    newQueryMenuItemActionPerformed(evt);
582                }
583            });
584
585        newMenu.add(newQueryMenuItem);
586
587        newJDBCExplorerMenuItem.setText(
588            getResourceConverter().getString(
589                "workbench.menu.newJDBC", "JDBC Explorer"));
590        newJDBCExplorerMenuItem.addActionListener(
591            new ActionListener() {
592                public void actionPerformed(ActionEvent evt) {
593                    newJDBCExplorerMenuItemActionPerformed(evt);
594                }
595            });
596
597        newMenu.add(newJDBCExplorerMenuItem);
598
599        fileMenu.add(newMenu);
600
601        openMenuItem.setText(
602            getResourceConverter().getString(
603                "workbench.menu.open", "Open"));
604        openMenuItem.addActionListener(
605            new ActionListener() {
606                public void actionPerformed(ActionEvent evt) {
607                    openMenuItemActionPerformed(evt);
608                }
609            });
610
611        fileMenu.add(openMenuItem);
612
613        saveMenuItem.setText(
614            getResourceConverter().getString(
615                "workbench.menu.save", "Save"));
616        saveMenuItem.addActionListener(
617            new ActionListener() {
618                public void actionPerformed(ActionEvent evt) {
619                    saveMenuItemActionPerformed(evt);
620                }
621            });
622
623        fileMenu.add(saveMenuItem);
624
625        saveAsMenuItem.setText(
626            getResourceConverter().getString(
627                "workbench.menu.saveAsDot", "Save As ..."));
628        saveAsMenuItem.addActionListener(
629            new ActionListener() {
630                public void actionPerformed(ActionEvent evt) {
631                    saveAsMenuItemActionPerformed(evt);
632                }
633            });
634
635        fileMenu.add(saveAsMenuItem);
636
637        //add last used
638        fileMenu.add(jSeparator2);
639
640        lastUsed1MenuItem.setText(getWorkbenchProperty("lastUsed1"));
641        lastUsed1MenuItem.addActionListener(
642            new ActionListener() {
643                public void actionPerformed(ActionEvent evt) {
644                    lastUsed1MenuItemActionPerformed(evt);
645                }
646            });
647        fileMenu.add(lastUsed1MenuItem);
648
649        lastUsed2MenuItem.setText(getWorkbenchProperty("lastUsed2"));
650        lastUsed2MenuItem.addActionListener(
651            new ActionListener() {
652                public void actionPerformed(ActionEvent evt) {
653                    lastUsed2MenuItemActionPerformed(evt);
654                }
655            });
656        fileMenu.add(lastUsed2MenuItem);
657
658        lastUsed3MenuItem.setText(getWorkbenchProperty("lastUsed3"));
659        lastUsed3MenuItem.addActionListener(
660            new ActionListener() {
661                public void actionPerformed(ActionEvent evt) {
662                    lastUsed3MenuItemActionPerformed(evt);
663                }
664            });
665        fileMenu.add(lastUsed3MenuItem);
666
667        lastUsed4MenuItem.setText(getWorkbenchProperty("lastUsed4"));
668        lastUsed4MenuItem.addActionListener(
669            new ActionListener() {
670                public void actionPerformed(ActionEvent evt) {
671                    lastUsed4MenuItemActionPerformed(evt);
672                }
673            });
674        fileMenu.add(lastUsed4MenuItem);
675
676        updateLastUsedMenu();
677        fileMenu.add(jSeparator1);
678
679        exitMenuItem.setText(
680            getResourceConverter().getString(
681                "workbench.menu.exit", "Exit"));
682        exitMenuItem.addActionListener(
683            new ActionListener() {
684                public void actionPerformed(ActionEvent evt) {
685                    exitMenuItemActionPerformed(evt);
686                }
687            });
688
689        fileMenu.add(exitMenuItem);
690
691        menuBar.add(fileMenu);
692
693        editMenu.setText(
694            getResourceConverter().getString(
695                "workbench.menu.edit", "Edit"));
696        editMenu.setMnemonic(KeyEvent.VK_E);
697        cutMenuItem.setText(
698            getResourceConverter().getString(
699                "workbench.menu.cut", "Cut"));
700        editMenu.add(cutMenuItem);
701
702        copyMenuItem.setText(
703            getResourceConverter().getString(
704                "workbench.menu.copy", "Copy"));
705        editMenu.add(copyMenuItem);
706
707        pasteMenuItem.setText(
708            getResourceConverter().getString(
709                "workbench.menu.paste", "Paste"));
710        editMenu.add(pasteMenuItem);
711
712        editMenu.add(deleteMenuItem);
713
714        menuBar.add(editMenu);
715
716        viewMenu.setText(
717            getResourceConverter().getString(
718                "workbench.menu.view", "View"));
719        viewMenu.setMnemonic(KeyEvent.VK_V);
720        viewXmlMenuItem.setText(
721            getResourceConverter().getString(
722                "workbench.menu.viewXML", "View XML"));
723        viewXmlMenuItem.addActionListener(
724            new ActionListener() {
725                public void actionPerformed(ActionEvent evt) {
726                    viewXMLMenuItemActionPerformed(evt);
727                }
728            });
729        viewMenu.add(viewXmlMenuItem);
730        menuBar.add(viewMenu);
731
732        toolsMenu.setText(getResourceConverter().getString(
733            "workbench.menu.options", "Options"));
734        toolsMenu.setMnemonic(KeyEvent.VK_O);
735        preferencesMenuItem.setText(getResourceConverter().getString(
736            "workbench.menu.connection", "Connection"));
737        preferencesMenuItem.addActionListener(
738            new ActionListener() {
739                public void actionPerformed(ActionEvent evt) {
740                    connectionButtonActionPerformed(evt);
741                }
742            });
743        toolsMenu.add(preferencesMenuItem);
744
745        requireSchemaCheckboxMenuItem.setText(
746            getResourceConverter().getString(
747                "workbench.menu.requireSchema", "Require Schema"));
748        requireSchemaCheckboxMenuItem.setSelected(requireSchema);
749        requireSchemaCheckboxMenuItem.addActionListener(
750            new ActionListener() {
751                public void actionPerformed(ActionEvent e) {
752                    requireSchemaActionPerformed(e);
753                }
754            });
755
756        toolsMenu.add(requireSchemaCheckboxMenuItem);
757        menuBar.add(toolsMenu);
758
759
760        windowMenu.setText(
761            getResourceConverter().getString(
762                "workbench.menu.windows", "Windows"));
763        windowMenu.setMnemonic(KeyEvent.VK_W);
764
765        cascadeMenuItem = new javax.swing.JMenuItem();
766        cascadeMenuItem.setText(
767            getResourceConverter().getString(
768                "workbench.menu.cascadeWindows", "Cascade Windows"));
769        cascadeMenuItem.addActionListener(
770            new ActionListener() {
771                public void actionPerformed(ActionEvent evt) {
772                    cascadeMenuItemActionPerformed(evt);
773                }
774            });
775
776        tileMenuItem = new javax.swing.JMenuItem();
777        tileMenuItem.setText(
778            getResourceConverter().getString(
779                "workbench.menu.tileWindows", "Tile Windows"));
780        tileMenuItem.addActionListener(
781            new ActionListener() {
782                public void actionPerformed(ActionEvent evt) {
783                    tileMenuItemActionPerformed(evt);
784                }
785            });
786
787        closeAllMenuItem = new javax.swing.JMenuItem();
788        closeAllMenuItem.setText(
789            getResourceConverter().getString(
790                "workbench.menu.closeAll", "Close All"));
791        closeAllMenuItem.addActionListener(
792            new ActionListener() {
793                public void actionPerformed(ActionEvent evt) {
794                    closeAllMenuItemActionPerformed(evt);
795                }
796            });
797
798        minimizeMenuItem = new javax.swing.JMenuItem();
799        minimizeMenuItem.setText(
800            getResourceConverter().getString(
801                "workbench.menu.minimizeAll", "Minimize All"));
802        minimizeMenuItem.addActionListener(
803            new ActionListener() {
804                public void actionPerformed(ActionEvent evt) {
805                    minimizeMenuItemActionPerformed(evt);
806                }
807            });
808
809        maximizeMenuItem = new javax.swing.JMenuItem();
810        maximizeMenuItem.setText(
811            getResourceConverter().getString(
812                "workbench.menu.maximizeAll", "Maximize All"));
813        maximizeMenuItem.addActionListener(
814            new ActionListener() {
815                public void actionPerformed(ActionEvent evt) {
816                    maximizeMenuItemActionPerformed(evt);
817                }
818            });
819
820        menuBar.add(windowMenu);
821
822        aboutMenuItem.setText(
823            getResourceConverter().getString(
824                "workbench.menu.about", "About"));
825        aboutMenuItem.addActionListener(
826            new ActionListener() {
827                public void actionPerformed(ActionEvent evt) {
828                    aboutMenuItemActionPerformed(evt);
829                }
830            });
831
832        helpMenu.add(aboutMenuItem);
833
834        helpMenu.setText(
835            getResourceConverter().getString(
836                "workbench.menu.help", "Help"));
837        helpMenu.setMnemonic(KeyEvent.VK_H);
838        menuBar.add(helpMenu);
839
840        setJMenuBar(menuBar);
841
842        pack();
843    }
844
845    /**
846     * this method loads any available menubar plugins based on
847     */
848    private void loadMenubarPlugins() {
849        // render any plugins
850        InputStream pluginStream = null;
851        try {
852            Properties props = new Properties();
853            pluginStream = getClass().getResourceAsStream(
854                "/workbench_plugins.properties");
855            if (pluginStream != null) {
856                props.load(pluginStream);
857                for (Object key : props.keySet()) {
858                    String keystr = (String) key;
859                    if (keystr.startsWith("workbench.menu-plugin")) {
860                        String val = props.getProperty(keystr);
861                        WorkbenchMenubarPlugin plugin =
862                            (WorkbenchMenubarPlugin) Class.forName(val)
863                                .newInstance();
864                        plugin.setWorkbench(this);
865                        plugin.addItemsToMenubar(menuBar);
866                    }
867                }
868            }
869        } catch (Exception e) {
870            e.printStackTrace();
871        } finally {
872            try {
873                if (pluginStream != null) {
874                    pluginStream.close();
875                }
876            } catch (Exception e) {
877            }
878        }
879    }
880
881
882    /**
883     * @return the workbenchResourceBundle
884     */
885    public ResourceBundle getWorkbenchResourceBundle() {
886        return workbenchResourceBundle;
887    }
888
889    /**
890     * @return the resourceConverter
891     */
892    public I18n getResourceConverter() {
893        if (resourceConverter == null) {
894            resourceConverter = getGlobalResourceConverter();
895        }
896        return resourceConverter;
897    }
898
899    private void tileMenuItemActionPerformed(ActionEvent evt) {
900        final Dimension dsize = desktopPane.getSize();
901        final int desktopW = (int) dsize.getWidth();
902        final int desktopH = (int) dsize.getHeight();
903        final int darea = desktopW * desktopH;
904        final double eacharea =
905            darea
906            / (schemaWindowMap.size() + mdxWindows.size() + jdbcWindows.size());
907        final int wh = (int) Math.sqrt(eacharea);
908
909        try {
910            int x = 0, y = 0;
911            for (JInternalFrame sf : getAllFrames()) {
912                if (sf != null && !sf.isIcon()) {
913                    sf.setMaximum(false);
914                    sf.moveToFront();
915                    if (x >= desktopW
916                        || (desktopW - x) * wh < eacharea / 2)
917                    {
918                        // move to next row of windows
919                        y += wh;
920                        x = 0;
921                    }
922                    int sfwidth = ((x + wh) < desktopW
923                        ? wh
924                        : desktopW - x);
925                    int sfheight = ((y + wh) < desktopH
926                        ? wh
927                        : desktopH - y);
928                    sf.setBounds(x, y, sfwidth, sfheight);
929                    x += sfwidth;
930                }
931            }
932        } catch (Exception ex) {
933            LOGGER.error("tileMenuItemActionPerformed", ex);
934            //do nothing
935        }
936    }
937
938    // cascade all the indows open in schema workbench
939    private void cascadeMenuItemActionPerformed(
940        ActionEvent evt)
941    {
942        try {
943            int sfi = 1;
944            for (JInternalFrame sf : getAllFrames()) {
945                if (sf != null && !sf.isIcon()) {
946                    sf.setMaximum(false);
947                    sf.setLocation(30 * sfi, 30 * sfi);
948                    sf.moveToFront();
949                    sf.setSelected(true);
950                    sfi++;
951                }
952            }
953        } catch (Exception ex) {
954            LOGGER.error("cascadeMenuItemActionPerformed", ex);
955            //do nothing
956        }
957    }
958
959    // close all the windows open in schema workbench
960    private void closeAllMenuItemActionPerformed(ActionEvent evt) {
961        closeAllSchemaFrames(false);
962    }
963
964    private void closeAllSchemaFrames(boolean exitAfterClose) {
965        try {
966            for (JInternalFrame sf : getAllFrames()) {
967                if (sf == null) {
968                    continue;
969                }
970                if (sf.getContentPane().getComponent(0)
971                    instanceof SchemaExplorer)
972                {
973                    SchemaExplorer se =
974                        (SchemaExplorer) sf.getContentPane().getComponent(0);
975                    sf.setSelected(true);
976                    int response = confirmFrameClose(sf, se);
977                    switch (response) {
978                    case 2:
979                        // cancel
980                        return;
981                    case 3:
982                        // not dirty
983                        sf.setClosed(true);
984                        break;
985                    }
986                } else {
987                    sf.setClosed(true);
988                }
989            }
990            // exit Schema Workbench if no files are open
991            if (((schemaWindowMap.keySet().size()) == 0) && exitAfterClose) {
992                System.exit(0);
993            }
994        } catch (Exception ex) {
995            LOGGER.error("closeAllSchemaFrames", ex);
996        }
997    }
998
999    private int confirmFrameClose(
1000        JInternalFrame schemaFrame,
1001        SchemaExplorer se)
1002    {
1003        if (se.isDirty()) {
1004            JMenuItem schemaMenuItem = schemaWindowMap.get(
1005                desktopPane.getSelectedFrame());
1006            // yes=0; no=1; cancel=2
1007            int answer = JOptionPane.showConfirmDialog(
1008                null,
1009                getResourceConverter().getFormattedString(
1010                    "workbench.saveSchemaOnClose.alert",
1011                    "Save changes to {0}?",
1012                    se.getSchemaFile().toString()),
1013                getResourceConverter().getString(
1014                    "workbench.saveSchemaOnClose.title", "Schema"),
1015                JOptionPane.YES_NO_CANCEL_OPTION);
1016            switch (answer) {
1017            case 0:
1018                saveMenuItemActionPerformed(null);
1019                schemaWindowMap.remove(schemaFrame);
1020                updateMDXCatalogList();
1021                schemaFrame.dispose();
1022                windowMenu.remove(schemaMenuItem);
1023                break;
1024            case 1:
1025                schemaFrame.dispose();
1026                schemaWindowMap.remove(schemaFrame);
1027                windowMenu.remove(schemaMenuItem);
1028                break;
1029            case 2:
1030                try {
1031                    schemaFrame.setClosed(false);
1032                    schemaFrame.show();
1033                } catch (Exception ex) {
1034                    LOGGER.error(ex);
1035                }
1036            }
1037            return answer;
1038        }
1039        return 3;
1040    }
1041
1042    private void minimizeMenuItemActionPerformed(
1043        ActionEvent evt)
1044    {
1045        try {
1046            for (JInternalFrame sf : getAllFrames()) {
1047                if (sf != null && !sf.isIcon()) {
1048                    sf.setIcon(true);
1049                }
1050            }
1051        } catch (Exception ex) {
1052            LOGGER.error("minimizeMenuItemActionPerformed", ex);
1053            //do nothing
1054        }
1055    }
1056
1057    private void maximizeMenuItemActionPerformed(
1058        ActionEvent evt)
1059    {
1060        try {
1061            for (JInternalFrame sf : getAllFrames()) {
1062                if (sf != null) {
1063                    sf.setIcon(false);
1064                    sf.setMaximum(true);
1065                }
1066            }
1067        } catch (Exception ex) {
1068            LOGGER.error("maximizeMenuItemActionPerformed", ex);
1069            //do nothing
1070        }
1071    }
1072
1073    /**
1074     * Returns an iterable over all internal frames.
1075     */
1076    @SuppressWarnings("unchecked")
1077    private Iterable<JInternalFrame> getAllFrames() {
1078        return UnionIterator.over(
1079            schemaWindowMap.keySet(), mdxWindows, jdbcWindows);
1080    }
1081
1082    private void aboutMenuItemActionPerformed(ActionEvent evt) {
1083        try {
1084            JEditorPane jEditorPane =
1085                new JEditorPane(
1086                    myClassLoader.getResource(
1087                        getResourceConverter().getGUIReference("version"))
1088                        .toString());
1089            jEditorPane.setEditable(false);
1090            JScrollPane jScrollPane = new JScrollPane(jEditorPane);
1091            JPanel jPanel = new JPanel();
1092            jPanel.setLayout(new java.awt.BorderLayout());
1093            jPanel.add(jScrollPane, java.awt.BorderLayout.CENTER);
1094
1095            JInternalFrame jf = new JInternalFrame();
1096            jf.setTitle("About");
1097            jf.getContentPane().add(jPanel);
1098
1099            Dimension screenSize = this.getSize();
1100            int aboutW = 400;
1101            int aboutH = 300;
1102            int width = (screenSize.width / 2) - (aboutW / 2);
1103            int height = (screenSize.height / 2) - (aboutH / 2) - 100;
1104            jf.setBounds(width, height, aboutW, aboutH);
1105            jf.setClosable(true);
1106
1107            desktopPane.add(jf);
1108
1109            jf.setVisible(true);
1110            jf.show();
1111        } catch (Exception ex) {
1112            LOGGER.error("aboutMenuItemActionPerformed", ex);
1113        }
1114    }
1115
1116    private void newJDBCExplorerMenuItemActionPerformed(
1117        ActionEvent evt)
1118    {
1119        try {
1120            if (jdbcMetaData == null) {
1121                getNewJdbcMetadata();
1122            }
1123
1124            final JInternalFrame jf = new JInternalFrame();
1125
1126            jf.setTitle(
1127                getResourceConverter().getFormattedString(
1128                    "workbench.new.JDBCExplorer.title",
1129                    "JDBC Explorer - {0} {1}",
1130                    jdbcMetaData.getDatabaseProductName(),
1131                    jdbcMetaData.getJdbcConnectionUrl()));
1132            getNewJdbcMetadata();
1133
1134            JdbcExplorer jdbce = new JdbcExplorer(jdbcMetaData, this);
1135
1136            jf.getContentPane().add(jdbce);
1137            jf.setBounds(0, 0, 500, 480);
1138            jf.setClosable(true);
1139            jf.setIconifiable(true);
1140            jf.setMaximizable(true);
1141            jf.setResizable(true);
1142            jf.setVisible(true);
1143
1144            // create jdbc menu item
1145            final javax.swing.JMenuItem jdbcMenuItem =
1146                new javax.swing.JMenuItem();
1147            jdbcMenuItem.setText(
1148                getResourceConverter().getFormattedString(
1149                    "workbench.new.JDBCExplorer.menuitem",
1150                    "{0} JDBC Explorer",
1151                    Integer.toString(windowMenuMapIndex++)));
1152            jdbcMenuItem.addActionListener(
1153                new ActionListener() {
1154                    public void actionPerformed(ActionEvent evt) {
1155                        try {
1156                            if (jf.isIcon()) {
1157                                jf.setIcon(false);
1158                            } else {
1159                                jf.setSelected(true);
1160                            }
1161                        } catch (Exception ex) {
1162                            LOGGER.error("queryMenuItem", ex);
1163                        }
1164                    }
1165                });
1166
1167            jf.addInternalFrameListener(
1168                new InternalFrameAdapter() {
1169                    public void internalFrameClosing(InternalFrameEvent e) {
1170                        jdbcWindows.remove(jf);
1171                        jf.dispose();
1172                        // follow this by removing file from schemaWindowMap
1173                        windowMenu.remove(jdbcMenuItem);
1174                        return;
1175                    }
1176                });
1177
1178            desktopPane.add(jf);
1179            jf.setVisible(true);
1180            jf.show();
1181
1182            try {
1183                jf.setSelected(true);
1184            } catch (Exception ex) {
1185                // do nothing
1186                LOGGER.error(
1187                    "newJDBCExplorerMenuItemActionPerformed.setSelected", ex);
1188            }
1189
1190            jdbcWindows.add(jf);
1191
1192            windowMenu.add(jdbcMenuItem, -1);
1193            windowMenu.add(jSeparator3, -1);
1194            windowMenu.add(cascadeMenuItem, -1);
1195            windowMenu.add(tileMenuItem, -1);
1196            windowMenu.add(minimizeMenuItem, -1);
1197            windowMenu.add(maximizeMenuItem, -1);
1198            windowMenu.add(closeAllMenuItem, -1);
1199        } catch (Exception ex) {
1200            JOptionPane.showMessageDialog(
1201                this,
1202                getResourceConverter().getFormattedString(
1203                    "workbench.new.JDBCExplorer.exception",
1204                    "Database connection not successful.\n{0}",
1205                    ex.getLocalizedMessage()),
1206                getResourceConverter().getString(
1207                    "workbench.new.JDBCExplorer.exception.title",
1208                    "Database Connection Error"),
1209                JOptionPane.ERROR_MESSAGE);
1210            LOGGER.error("newJDBCExplorerMenuItemActionPerformed", ex);
1211        }
1212    }
1213
1214    /**
1215     * Convenience method for retrieving the dbMeta instance that handles
1216     * required Kettle initialization.
1217     *
1218     * @param xml
1219     *            output of {@link DatabaseMeta#getXML()} or <code>null</code>
1220     * @return the current {@link DatabaseMeta} instance
1221     */
1222    private DatabaseMeta getDbMeta(String xml) {
1223        try {
1224            if (!KettleClientEnvironment.isInitialized()) {
1225                System.setProperty(
1226                    "KETTLE_PLUGIN_BASE_FOLDERS",
1227                    KETTLE_PLUGIN_BASE_FOLDERS);
1228                KettleClientEnvironment.init();
1229            }
1230            if (dbMeta != null) {
1231                return dbMeta;
1232            }
1233            if (xml == null) {
1234                dbMeta = new DatabaseMeta();
1235            } else {
1236                dbMeta = new DatabaseMeta(xml);
1237            }
1238        } catch (KettleException e) {
1239            throw new RuntimeException(
1240                getResourceConverter().getFormattedString(
1241                    "workbench.new.Kettle.exception",
1242                    "Kettle failed to initialize."),
1243                e);
1244        }
1245        return dbMeta;
1246    }
1247
1248    private void connectionButtonActionPerformed(ActionEvent evt) {
1249        if (connectionDialog == null) {
1250            dbMeta = getDbMeta(null);
1251            connectionDialogController = new DataHandler();
1252            connectionDialogController.setName("dataHandler");
1253
1254            XulDomContainer container = null;
1255
1256            try {
1257                XulLoader loader = new SwingXulLoader();
1258                container = loader.loadXul(
1259                    DatabaseConnectionDialog.DIALOG_DEFINITION_FILE,
1260                    Messages.getBundle());
1261            } catch (XulException e) {
1262                throw new RuntimeException("Xul failed to initialize", e);
1263            }
1264            container.addEventHandler(connectionDialogController);
1265            connectionDialogController.loadConnectionData();
1266            connectionDialogController.setData(dbMeta);
1267            connectionDialog = (XulDialog) container.getDocumentRoot()
1268                    .getRootElement();
1269        }
1270
1271        connectionDialog.show();
1272
1273        dbMeta = (DatabaseMeta) connectionDialogController.getData();
1274        if (dbMeta.hasChanged()) {
1275            dbMeta.clearChanged();
1276            syncToWorkspace(dbMeta);
1277            // Enforces the JDBC preferences entered throughout all schemas
1278            //currently opened in the workbench.
1279            resetWorkbench();
1280        }
1281    }
1282
1283    private void syncToWorkspace(DatabaseMeta databaseMeta) {
1284        // sync from dbmeta to wkspc
1285        try {
1286            jdbcConnectionUrl = databaseMeta.getURL();
1287        } catch (KettleDatabaseException e) {
1288            throw new RuntimeException("Failed to determine JDBC URL", e);
1289        }
1290        jdbcDriverClassName = databaseMeta.getDriverClass();
1291        jdbcUsername = databaseMeta.getUsername();
1292        jdbcPassword = databaseMeta.getPassword();
1293        //jdbcSchema = databaseMeta.getPreferredSchemaName();
1294        Map<String, String> options = dbMeta.getExtraOptions();
1295
1296        String dbType = dbMeta.getDatabaseInterface().getPluginId();
1297        jdbcSchema = options.get(dbType + "." + FILTER_SCHEMA_LIST);
1298
1299        // saving to workbench properties for documentation purposes only, since
1300        // persistence
1301        // of the dbmeta object is handled by a separate xml file now
1302        if (jdbcDriverClassName != null) {
1303            setWorkbenchProperty("jdbcDriverClassName", jdbcDriverClassName);
1304        }
1305        if (jdbcConnectionUrl != null) {
1306            setWorkbenchProperty("jdbcConnectionUrl", jdbcConnectionUrl);
1307        }
1308        if (jdbcUsername != null) {
1309            setWorkbenchProperty("jdbcUsername", jdbcUsername);
1310        }
1311        if (jdbcPassword != null) {
1312            setWorkbenchProperty("jdbcPassword", jdbcPassword);
1313        }
1314        if (jdbcSchema != null) {
1315            setWorkbenchProperty("jdbcSchema", jdbcSchema);
1316        }
1317    }
1318
1319    private void requireSchemaActionPerformed(ActionEvent evt) {
1320        requireSchema = ((JCheckBoxMenuItem) evt.getSource()).isSelected();
1321        setWorkbenchProperty("requireSchema", "" + requireSchema);
1322    }
1323
1324
1325    private void newSchemaMenuItemActionPerformed(ActionEvent evt) {
1326        MondrianProperties.instance();
1327        // User's default directory. This default depends on the operating
1328        // system.  It is typically the "My Documents" folder on Windows, and
1329        // the user's home directory on Unix.
1330        File defaultDir =
1331            FileSystemView.getFileSystemView().getDefaultDirectory();
1332        File outputFile;
1333        do {
1334            outputFile = new File(defaultDir, "Schema" + newSchema++ + ".xml");
1335        } while (outputFile.exists());
1336
1337        openSchemaFrame(outputFile, true);
1338    }
1339
1340    private void newQueryMenuItemActionPerformed(ActionEvent evt) {
1341        JMenuItem schemaMenuItem =
1342            schemaWindowMap.get(desktopPane.getSelectedFrame());
1343
1344        final JInternalFrame jf = new JInternalFrame();
1345        jf.setTitle(
1346            getResourceConverter().getString(
1347                "workbench.new.MDXQuery.title", "MDX Query"));
1348        QueryPanel qp = new QueryPanel(this);
1349
1350        jf.getContentPane().add(qp);
1351        jf.setBounds(0, 0, 500, 480);
1352        jf.setClosable(true);
1353        jf.setIconifiable(true);
1354        jf.setMaximizable(true);
1355        jf.setResizable(true);
1356        jf.setVisible(true);
1357
1358        desktopPane.add(jf);
1359        jf.show();
1360        try {
1361            jf.setSelected(true);
1362        } catch (Exception ex) {
1363            // do nothing
1364            LOGGER.error("newQueryMenuItemActionPerformed.setSelected", ex);
1365        }
1366
1367        // add the mdx frame to this set of mdx frames for cascading method
1368        mdxWindows.add(jf);
1369
1370        // create mdx menu item
1371        final javax.swing.JMenuItem queryMenuItem = new javax.swing.JMenuItem();
1372        queryMenuItem.setText(
1373            getResourceConverter().getFormattedString(
1374                "workbench.new.MDXQuery.menuitem",
1375                "{0} MDX",
1376                Integer.toString(windowMenuMapIndex)));
1377        queryMenuItem.addActionListener(
1378            new ActionListener() {
1379                public void actionPerformed(ActionEvent evt) {
1380                    try {
1381                        if (jf.isIcon()) {
1382                            jf.setIcon(false);
1383                        } else {
1384                            jf.setSelected(true);
1385                        }
1386                    } catch (Exception ex) {
1387                        LOGGER.error("queryMenuItem", ex);
1388                    }
1389                }
1390            });
1391
1392        // disable mdx frame close operation to provide our handler
1393        // to remove frame object from mdxframeset before closing
1394        jf.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
1395
1396        jf.addInternalFrameListener(
1397            new InternalFrameAdapter() {
1398                public void internalFrameClosing(InternalFrameEvent e) {
1399                    mdxWindows.remove(jf);
1400                    jf.dispose();
1401                    // follow this by removing file from schemaWindowMap
1402                    windowMenu.remove(queryMenuItem);
1403                    return;
1404                }
1405            });
1406
1407        windowMenu.add(queryMenuItem, -1);
1408        windowMenu.add(jSeparator3, -1);
1409        windowMenu.add(cascadeMenuItem, -1);
1410        windowMenu.add(tileMenuItem, -1);
1411        windowMenu.add(minimizeMenuItem, -1);
1412        windowMenu.add(maximizeMenuItem, -1);
1413        windowMenu.add(closeAllMenuItem, -1);
1414
1415        qp.setMenuItem(queryMenuItem);
1416        qp.setSchemaWindowMap(schemaWindowMap);
1417        qp.setWindowMenuIndex(windowMenuMapIndex++);
1418
1419        if (schemaMenuItem != null) {
1420            qp.initConnection(schemaMenuItem.getText());
1421        } else {
1422            JOptionPane.showMessageDialog(
1423                this, getResourceConverter().getString(
1424                    "workbench.new.MDXQuery.no.selection",
1425                    "No Mondrian connection. Select a Schema to connect."),
1426                getResourceConverter().getString(
1427                    "workbench.new.MDXQuery.no.selection.title", "Alert"),
1428                JOptionPane.WARNING_MESSAGE);
1429        }
1430    }
1431
1432    // inform all opened mdx query windows about the list of opened schema files
1433    private void updateMDXCatalogList() {
1434        Iterator<JInternalFrame> it = mdxWindows.iterator();
1435        while (it.hasNext()) {
1436            JInternalFrame elem = it.next();
1437            QueryPanel qp = (QueryPanel) elem.getContentPane().getComponent(0);
1438            qp.setSchemaWindowMap(schemaWindowMap);
1439        }
1440    }
1441
1442    /**
1443     * returns the currently selected schema explorer object
1444     *
1445     * @return current schema explorer object
1446     */
1447    public SchemaExplorer getCurrentSchemaExplorer() {
1448        JInternalFrame jf = desktopPane.getSelectedFrame();
1449        if (jf != null && jf.getContentPane().getComponentCount() > 0 && jf
1450            .getContentPane().getComponent(0) instanceof SchemaExplorer)
1451        {
1452            return (SchemaExplorer) jf.getContentPane().getComponent(0);
1453        }
1454        return null;
1455    }
1456
1457    private void saveAsMenuItemActionPerformed(ActionEvent evt) {
1458        JInternalFrame jf = desktopPane.getSelectedFrame();
1459
1460        if (jf != null && jf.getContentPane()
1461            .getComponent(0) instanceof SchemaExplorer)
1462        {
1463            SchemaExplorer se =
1464                (SchemaExplorer) jf.getContentPane().getComponent(0);
1465            java.io.File schemaFile = se.getSchemaFile();
1466            java.io.File oldSchemaFile = schemaFile;
1467            java.io.File suggSchemaFile = new File(
1468                schemaFile == null
1469                    ? se.getSchema().name.trim() + ".xml"
1470                    : schemaFile.getName());
1471            MondrianGuiDef.Schema schema = se.getSchema();
1472            JFileChooser jfc = new JFileChooser();
1473            MondrianProperties.instance();
1474
1475            jfc.setSelectedFile(suggSchemaFile);
1476
1477            if (jfc.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) {
1478                try {
1479                    schemaFile = jfc.getSelectedFile();
1480                    if (!oldSchemaFile.equals(schemaFile) && schemaFile
1481                        .exists())
1482                    {  //new file already exists, check for overwrite
1483                        int answer = JOptionPane.showConfirmDialog(
1484                            null,
1485                            getResourceConverter().getFormattedString(
1486                                "workbench.saveAs.schema.confirm",
1487                                "{0} schema file already exists. Do you want to replace it?",
1488                                schemaFile.getAbsolutePath()),
1489                            getResourceConverter().getString(
1490                                "workbench.saveAs.schema.confirm.title",
1491                                "Save As"),
1492                            JOptionPane.YES_NO_OPTION);
1493                        if (answer == 1) { //  no=1 ; yes=0
1494                            return;
1495                        }
1496                    }
1497
1498                    if (se.isNewFile() && !oldSchemaFile.equals(schemaFile)) {
1499                        oldSchemaFile.delete();
1500                    }
1501
1502                    if (se.isNewFile()) {
1503                        se.setNewFile(false);
1504                    }
1505                    se.setDirty(false);
1506                    se.setDirtyFlag(false);
1507
1508                    XMLOutput out =
1509                        new XMLOutput(
1510                            new java.io.FileWriter(jfc.getSelectedFile()));
1511                    out.setAlwaysQuoteCData(true);
1512                    out.setIndentString("  ");
1513                    schema.displayXML(out);
1514                    se.setSchemaFile(schemaFile);
1515                    se.setTitle();  //sets title of iframe
1516                    setLastUsed(
1517                        jfc.getSelectedFile().getName(),
1518                        jfc.getSelectedFile().toURI().toURL().toString());
1519
1520                    // Update menu item with new file name, then update catalog
1521                    // list for mdx queries
1522                    JMenuItem sMenuItem = schemaWindowMap.get(jf);
1523                    String mtexttokens[] = sMenuItem.getText().split(" ");
1524                    sMenuItem.setText(
1525                        mtexttokens[0] + " " + se.getSchemaFile().getName());
1526                    // Schema menu item updated, now update mdx query windows
1527                    // with updated catalog list.
1528                    updateMDXCatalogList();
1529                } catch (Exception ex) {
1530                    LOGGER.error(ex);
1531                }
1532            }
1533        }
1534    }
1535
1536    private void viewXMLMenuItemActionPerformed(ActionEvent evt) {
1537        JInternalFrame jf = desktopPane.getSelectedFrame();
1538        boolean oldValue = viewXmlMenuItem.getState();
1539        if (jf != null
1540            && jf.getContentPane().getComponent(0) instanceof SchemaExplorer)
1541        {
1542            SchemaExplorer se =
1543                (SchemaExplorer) jf.getContentPane().getComponent(0);
1544            // Call schema explorer's view xml event and update the workbench's
1545            // view menu accordingly'
1546            ((JCheckBoxMenuItem) evt.getSource()).setSelected(se.editMode(evt));
1547            return;
1548        }
1549        viewXmlMenuItem.setSelected(!oldValue);
1550    }
1551
1552    public void saveMenuItemActionPerformed(ActionEvent evt) {
1553        JInternalFrame jf = desktopPane.getSelectedFrame();
1554
1555        // Don't save if nothing there
1556        if (jf == null || jf.getContentPane() == null) {
1557            return;
1558        }
1559
1560        if (jf.getContentPane().getComponent(0) instanceof SchemaExplorer) {
1561            SchemaExplorer se =
1562                (SchemaExplorer) jf.getContentPane().getComponent(0);
1563
1564            java.io.File schemaFile = se.getSchemaFile();
1565
1566            if (se.isNewFile()) {
1567                saveAsMenuItemActionPerformed(evt);
1568                return;
1569            }
1570
1571            se.setDirty(false);
1572            se.setDirtyFlag(false);
1573            se.setTitle();  //sets title of iframe
1574
1575            MondrianGuiDef.Schema schema = se.getSchema();
1576            MondrianProperties.instance();
1577            try {
1578                XMLOutput out = new XMLOutput(new FileWriter(schemaFile));
1579                out.setAlwaysQuoteCData(true);
1580                out.setIndentString("  ");
1581                schema.displayXML(out);
1582                setLastUsed(
1583                    schemaFile.getName(),
1584                    schemaFile.toURI().toURL().toString());
1585            } catch (Exception ex) {
1586                LOGGER.error("saveMenuItemActionPerformed", ex);
1587            }
1588        }
1589    }
1590
1591    /**
1592     * Set last used in properties file
1593     *
1594     * @param name
1595     * @param url
1596     */
1597    private void setLastUsed(String name, String url) {
1598        int match = 4;
1599        String luName = null;
1600        String propname = null;
1601        String lastUsed = "lastUsed";
1602        String lastUsedUrl = "lastUsedUrl";
1603        for (int i = 1; i <= 4; i++) {
1604            propname = lastUsed + i;
1605            luName = getWorkbenchProperty(propname);
1606
1607            if (luName != null && luName.equals(name)) {
1608                match = i;
1609                break;
1610            }
1611        }
1612
1613        for (int i = match; i > 1; i--) {
1614            if (getWorkbenchProperty(lastUsed + (i - 1)) != null) {
1615                setWorkbenchProperty(
1616                    lastUsed + i, getWorkbenchProperty(
1617                        lastUsed + (i - 1)));
1618                setWorkbenchProperty(
1619                    lastUsedUrl + i, getWorkbenchProperty(
1620                        lastUsedUrl + (i - 1)));
1621            }
1622        }
1623
1624        setWorkbenchProperty(LAST_USED1, name);
1625        setWorkbenchProperty(LAST_USED1_URL, url);
1626        updateLastUsedMenu();
1627        storeWorkbenchProperties();
1628        storeDatabaseMeta();
1629    }
1630
1631    private void updateLastUsedMenu() {
1632        if (getWorkbenchProperty(LAST_USED1) == null) {
1633            jSeparator2.setVisible(false);
1634        } else {
1635            jSeparator2.setVisible(true);
1636        }
1637
1638        if (getWorkbenchProperty(LAST_USED1) != null) {
1639            lastUsed1MenuItem.setVisible(true);
1640        } else {
1641            lastUsed1MenuItem.setVisible(false);
1642        }
1643        if (getWorkbenchProperty(LAST_USED2) != null) {
1644            lastUsed2MenuItem.setVisible(true);
1645        } else {
1646            lastUsed2MenuItem.setVisible(false);
1647        }
1648        if (getWorkbenchProperty(LAST_USED3) != null) {
1649            lastUsed3MenuItem.setVisible(true);
1650        } else {
1651            lastUsed3MenuItem.setVisible(false);
1652        }
1653        if (getWorkbenchProperty(LAST_USED4) != null) {
1654            lastUsed4MenuItem.setVisible(true);
1655        } else {
1656            lastUsed4MenuItem.setVisible(false);
1657        }
1658
1659        lastUsed1MenuItem.setText(getWorkbenchProperty(LAST_USED1));
1660        lastUsed2MenuItem.setText(getWorkbenchProperty(LAST_USED2));
1661        lastUsed3MenuItem.setText(getWorkbenchProperty(LAST_USED3));
1662        lastUsed4MenuItem.setText(getWorkbenchProperty(LAST_USED4));
1663    }
1664
1665    private void lastUsed1MenuItemActionPerformed(ActionEvent evt) {
1666        try {
1667            openSchemaFrame(
1668                new File(new URI(getWorkbenchProperty(LAST_USED1_URL))), false);
1669        } catch (Exception e) {
1670            // probably URISyntaxException
1671            LOGGER.error("lastUsed1MenuItemActionPerformed", e);
1672        }
1673    }
1674
1675    private void lastUsed2MenuItemActionPerformed(ActionEvent evt) {
1676        try {
1677            openSchemaFrame(
1678                new File(new URI(getWorkbenchProperty(LAST_USED2_URL))), false);
1679            setLastUsed(
1680                getWorkbenchProperty(LAST_USED2), getWorkbenchProperty(
1681                    LAST_USED2_URL));
1682        } catch (URISyntaxException e) {
1683            LOGGER.error("lastUsed2MenuItemActionPerformed", e);
1684        }
1685    }
1686
1687    private void lastUsed3MenuItemActionPerformed(ActionEvent evt) {
1688        try {
1689            openSchemaFrame(
1690                new File(new URI(getWorkbenchProperty(LAST_USED3_URL))), false);
1691            setLastUsed(
1692                getWorkbenchProperty(LAST_USED3), getWorkbenchProperty(
1693                    LAST_USED3_URL));
1694        } catch (URISyntaxException e) {
1695            LOGGER.error("lastUsed3MenuItemActionPerformed", e);
1696        }
1697    }
1698
1699    private void lastUsed4MenuItemActionPerformed(ActionEvent evt) {
1700        try {
1701            openSchemaFrame(
1702                new File(new URI(getWorkbenchProperty(LAST_USED4_URL))), false);
1703            setLastUsed(
1704                getWorkbenchProperty(LAST_USED4), getWorkbenchProperty(
1705                    LAST_USED4_URL));
1706        } catch (URISyntaxException e) {
1707            LOGGER.error("lastUsed4MenuItemActionPerformed", e);
1708        }
1709    }
1710
1711    /**
1712     * @param file
1713     */
1714    private void openSchemaFrame(File file, boolean newFile) {
1715        try {
1716            setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
1717
1718            if (!newFile) {
1719                // check if file not already open
1720                if (checkFileOpen(file)) {
1721                    return;
1722                }
1723                // check if schema file exists
1724                if (!file.exists()) {
1725                    JOptionPane.showMessageDialog(
1726                        this,
1727                        getResourceConverter().getFormattedString(
1728                            "workbench.open.schema.not.found",
1729                            "{0} File not found.",
1730                            file.getAbsolutePath()),
1731                        getResourceConverter().getString(
1732                            "workbench.open.schema.not.found.title", "Alert"),
1733                        JOptionPane.WARNING_MESSAGE);
1734                    return;
1735                }
1736                // check if file is writable
1737                if (!file.canWrite()) {
1738                    JOptionPane.showMessageDialog(
1739                        this,
1740                        getResourceConverter().getFormattedString(
1741                            "workbench.open.schema.not.writeable",
1742                            "{0} is not writeable.",
1743                            file.getAbsolutePath()),
1744                        getResourceConverter().getString(
1745                            "workbench.open.schema.not.writeable.title",
1746                            "Alert"),
1747                        JOptionPane.WARNING_MESSAGE);
1748                    return;
1749                }
1750                checkSchemaFile(file);
1751            }
1752
1753            final JInternalFrame schemaFrame = new JInternalFrame();
1754            schemaFrame.setTitle(
1755                getResourceConverter().getFormattedString(
1756                    "workbench.open.schema.title",
1757                    "Schema - {0}",
1758                    file.getName()));
1759
1760            getNewJdbcMetadata();
1761
1762            schemaFrame.getContentPane().add(
1763                new SchemaExplorer(
1764                    this, file, jdbcMetaData, newFile, schemaFrame));
1765
1766            String errorOpening =
1767                ((SchemaExplorer) schemaFrame.getContentPane().getComponent(0))
1768                    .getErrMsg();
1769            if (errorOpening != null) {
1770                JOptionPane.showMessageDialog(
1771                    this,
1772                    getResourceConverter().getFormattedString(
1773                        "workbench.open.schema.error",
1774                        "Error opening schema - {0}.",
1775                        errorOpening),
1776                    getResourceConverter().getString(
1777                        "workbench.open.schema.error.title", "Error"),
1778                    JOptionPane.ERROR_MESSAGE);
1779                schemaFrame.setClosed(true);
1780                return;
1781            }
1782
1783            schemaFrame.setBounds(0, 0, 1000, 650);
1784            schemaFrame.setClosable(true);
1785            schemaFrame.setIconifiable(true);
1786            schemaFrame.setMaximizable(true);
1787            schemaFrame.setResizable(true);
1788            schemaFrame.setVisible(true);
1789
1790            desktopPane.add(
1791                schemaFrame, javax.swing.JLayeredPane.DEFAULT_LAYER);
1792            schemaFrame.show();
1793            schemaFrame.setMaximum(true);
1794
1795            displayWarningOnFailedConnection();
1796
1797            final javax.swing.JMenuItem schemaMenuItem =
1798                new javax.swing.JMenuItem();
1799            schemaMenuItem.setText(windowMenuMapIndex++ + " " + file.getName());
1800            schemaMenuItem.addActionListener(
1801                new ActionListener() {
1802                    public void actionPerformed(ActionEvent evt) {
1803                        try {
1804                            if (schemaFrame.isIcon()) {
1805                                schemaFrame.setIcon(false);
1806                            } else {
1807                                schemaFrame.setSelected(true);
1808                            }
1809                        } catch (Exception ex) {
1810                            LOGGER.error("schemaMenuItem", ex);
1811                        }
1812                    }
1813                });
1814
1815            windowMenu.add(schemaMenuItem, 0);
1816            windowMenu.setEnabled(true);
1817
1818            windowMenu.add(jSeparator3, -1);
1819            windowMenu.add(cascadeMenuItem, -1);
1820            windowMenu.add(tileMenuItem, -1);
1821            windowMenu.add(minimizeMenuItem, -1);
1822            windowMenu.add(maximizeMenuItem, -1);
1823            windowMenu.add(closeAllMenuItem, -1);
1824
1825            // add the file details in menu map
1826            schemaWindowMap.put(schemaFrame, schemaMenuItem);
1827            updateMDXCatalogList();
1828
1829            schemaFrame.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
1830
1831            schemaFrame.addInternalFrameListener(
1832                new InternalFrameAdapter() {
1833                    public void internalFrameClosing(InternalFrameEvent e) {
1834                        if (schemaFrame.getContentPane()
1835                            .getComponent(0) instanceof SchemaExplorer)
1836                        {
1837                            SchemaExplorer se =
1838                                (SchemaExplorer) schemaFrame.getContentPane()
1839                                    .getComponent(0);
1840                            int response = confirmFrameClose(schemaFrame, se);
1841                            if (response == 3) {    // not dirty
1842                                if (se.isNewFile()) {
1843                                    se.getSchemaFile().delete();
1844                                }
1845                                // default case for no save and not dirty
1846                                schemaWindowMap.remove(schemaFrame);
1847                                updateMDXCatalogList();
1848                                schemaFrame.dispose();
1849                                windowMenu.remove(schemaMenuItem);
1850                            }
1851                        }
1852                    }
1853                });
1854
1855            schemaFrame.setFocusable(true);
1856            schemaFrame.addFocusListener(
1857                new FocusAdapter() {
1858                    public void focusGained(FocusEvent e) {
1859                        if (schemaFrame.getContentPane()
1860                            .getComponent(0) instanceof SchemaExplorer)
1861                        {
1862                            SchemaExplorer se = (SchemaExplorer)
1863                                schemaFrame.getContentPane().getComponent(0);
1864                            // update view menu based on schemaframe who gained
1865                            // focus
1866                            viewXmlMenuItem.setSelected(
1867                                se.isEditModeXML());
1868                        }
1869                    }
1870
1871                    public void focusLost(FocusEvent e) {
1872                        if (schemaFrame.getContentPane()
1873                            .getComponent(0) instanceof SchemaExplorer)
1874                        {
1875                            SchemaExplorer se = (SchemaExplorer)
1876                                schemaFrame.getContentPane().getComponent(0);
1877                            // update view menu based on
1878                            viewXmlMenuItem.setSelected(
1879                                se.isEditModeXML());
1880                        }
1881                    }
1882                });
1883            viewXmlMenuItem.setSelected(false);
1884        } catch (Exception ex) {
1885            LOGGER.error("openSchemaFrame", ex);
1886        } finally {
1887            setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
1888        }
1889    }
1890
1891    private void openMenuItemActionPerformed(ActionEvent evt) {
1892        JFileChooser jfc = new JFileChooser();
1893        try {
1894            jfc.setFileSelectionMode(JFileChooser.FILES_ONLY);
1895            jfc.setFileFilter(
1896                new javax.swing.filechooser.FileFilter() {
1897                    public boolean accept(File pathname) {
1898                        return pathname.getName().toLowerCase().endsWith(".xml")
1899                               || pathname.isDirectory();
1900                    }
1901
1902                    public String getDescription() {
1903                        return getResourceConverter().getString(
1904                            "workbench.open.schema.file.type",
1905                            "Mondrian Schema files (*.xml)");
1906                    }
1907                });
1908
1909            String lastUsed = getWorkbenchProperty(LAST_USED1_URL);
1910
1911            if (lastUsed != null) {
1912                jfc.setCurrentDirectory(new File(new URI(lastUsed)));
1913            }
1914        } catch (Exception ex) {
1915            LOGGER.error("Could not set file chooser", ex);
1916        }
1917        MondrianProperties.instance();
1918        if (jfc.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
1919            try {
1920                setLastUsed(
1921                    jfc.getSelectedFile().getName(),
1922                    jfc.getSelectedFile().toURI().toURL().toString());
1923            } catch (MalformedURLException e) {
1924                LOGGER.error(e);
1925            }
1926
1927            openSchemaFrame(jfc.getSelectedFile(), false);
1928        }
1929    }
1930
1931    // checks if file already open in schema explorer
1932    private boolean checkFileOpen(File file) {
1933        Iterator<JInternalFrame> it = schemaWindowMap.keySet().iterator();  // keys=schemaframes
1934        while (it.hasNext()) {
1935            JInternalFrame elem = it.next();
1936            File f = ((SchemaExplorer) elem.getContentPane().getComponent(0))
1937                .getSchemaFile();
1938            if (f.equals(file)) {
1939                try {
1940                    // make the schema file active
1941                    elem.setSelected(true);
1942                    return true;
1943                } catch (Exception ex) {
1944                    // remove file from map as schema frame does not exist
1945                    schemaWindowMap.remove(elem);
1946                    break;
1947                }
1948            }
1949        }
1950        return false;
1951    }
1952
1953    private void getNewJdbcMetadata() {
1954        jdbcMetaData = new JdbcMetaData(
1955            this,
1956            jdbcDriverClassName,
1957            jdbcConnectionUrl,
1958            jdbcUsername,
1959            jdbcPassword,
1960            jdbcSchema,
1961            requireSchema);
1962    }
1963
1964    /**
1965     * Updates the JdbcMetaData for each SchemaExplorer contained in each Schema
1966     * Frame currently opened based on the JDBC preferences entered.
1967     */
1968    private void resetWorkbench() {
1969        getNewJdbcMetadata();
1970
1971        Iterator<JInternalFrame> theSchemaFrames =
1972            schemaWindowMap.keySet().iterator();
1973        while (theSchemaFrames.hasNext()) {
1974            JInternalFrame theSchemaFrame =
1975                theSchemaFrames.next();
1976            SchemaExplorer theSchemaExplorer =
1977                (SchemaExplorer) theSchemaFrame.getContentPane()
1978                    .getComponent(0);
1979            File theFile = theSchemaExplorer.getSchemaFile();
1980            checkSchemaFile(theFile);
1981            theSchemaExplorer.resetMetaData(jdbcMetaData);
1982            theSchemaExplorer.getTreeUpdater().update();
1983            theSchemaFrame.updateUI();
1984        }
1985        //EC: If the JDBC preferences entered then display a warning.
1986        displayWarningOnFailedConnection();
1987
1988        for (JInternalFrame jdbcFrame : jdbcWindows) {
1989            JdbcExplorer explorer =
1990                (JdbcExplorer) jdbcFrame.getContentPane().getComponent(0);
1991            explorer.resetMetaData(jdbcMetaData);
1992
1993            jdbcFrame.setTitle(
1994                getResourceConverter().getFormattedString(
1995                    "workbench.new.JDBCExplorer.title",
1996                    "JDBC Explorer - {0} {1}",
1997                    jdbcMetaData.getDatabaseProductName(),
1998                    jdbcMetaData.getJdbcConnectionUrl()));
1999
2000            explorer.getTreeUpdater().update();
2001            explorer.updateUI();
2002        }
2003    }
2004
2005    /**
2006     * Display jdbc connection status warning, if connection is uncsuccessful.
2007     */
2008    private void displayWarningOnFailedConnection() {
2009        if (jdbcMetaData != null && jdbcMetaData.getErrMsg() != null) {
2010            JOptionPane.showMessageDialog(
2011                this,
2012                getResourceConverter().getFormattedString(
2013                    "workbench.open.schema.jdbc.error",
2014                    "Database connection could not be done.\n{0}\nAll validations related to database will be ignored.",
2015                    jdbcMetaData.getErrMsg()),
2016                getResourceConverter().getString(
2017                    "workbench.open.schema.jdbc.error.title", "Alert"),
2018                JOptionPane.WARNING_MESSAGE);
2019        }
2020    }
2021
2022    /**
2023     * Check if schema file is valid by initiating a mondrian connection.
2024     */
2025    private void checkSchemaFile(File file) {
2026        try {
2027            // this connection parses the catalog file which if invalid will
2028            // throw exception
2029            PropertyList list = new PropertyList();
2030            list.put("Provider", "mondrian");
2031            list.put("Jdbc", jdbcConnectionUrl);
2032            list.put("Catalog", file.toURI().toURL().toString());
2033            list.put("JdbcDrivers", jdbcDriverClassName);
2034            if (jdbcUsername != null && jdbcUsername.length() > 0) {
2035                list.put("JdbcUser", jdbcUsername);
2036            }
2037            if (jdbcPassword != null && jdbcPassword.length() > 0) {
2038                list.put("JdbcPassword", jdbcPassword);
2039            }
2040
2041            DriverManager.getConnection(list, null);
2042        } catch (Exception ex) {
2043            LOGGER.error(
2044                "Exception : Schema file "
2045                + file.getAbsolutePath()
2046                + " is invalid."
2047                + ex.getMessage(), ex);
2048        } catch (Error err) {
2049            LOGGER.error(
2050                "Error : Schema file "
2051                + file.getAbsolutePath()
2052                + " is invalid."
2053                + err.getMessage(), err);
2054        }
2055    }
2056
2057
2058    private void exitMenuItemActionPerformed(ActionEvent evt) {
2059        storeWorkbenchProperties();
2060        storeDatabaseMeta();
2061        closeAllSchemaFrames(true);
2062    }
2063
2064    /**
2065     * Parses arguments passed into Workbench.
2066     *
2067     * <p>Right now, it's very simple.  Just search through the list of
2068     * arguments.  If it begins with -f=, then the rest is a file name.  Ignore
2069     * any others.  We can make this more complicated later if we need to.
2070     *
2071     * @param args the command line arguments
2072     */
2073    private void parseArgs(String args[]) {
2074        for (int argNum = 0; argNum < args.length; argNum++) {
2075            if (args[argNum].startsWith("-f=")) {
2076                openFile = args[argNum].substring(3);
2077            }
2078        }
2079    }
2080
2081    public String getTooltip(String titleName) {
2082        try {
2083            return getWorkbenchResourceBundle().getString(titleName);
2084        } catch (MissingResourceException e) {
2085            return getResourceConverter().getFormattedString(
2086                "workbench.tooltip.error",
2087                "No help available for {0}",
2088                titleName);
2089        }
2090    }
2091
2092    /**
2093     * @param args the command line arguments
2094     */
2095    public static void main(String args[]) {
2096        Workbench w = null;
2097        try {
2098            w = new Workbench();
2099            w.parseArgs(args);
2100            w.setSize(800, 600);
2101            // if user specified a file to open, do so now.
2102            if (w.openFile != null) {
2103                File f = new File(w.openFile);
2104                if (f.canRead()) {
2105                    w.openSchemaFrame(
2106                        f.getAbsoluteFile(),
2107                        // parameter to indicate this is a new or existing
2108                        // catalog file
2109                        false);
2110                }
2111            }
2112            w.setVisible(true);
2113        } catch (Throwable ex) {
2114            if (w != null) {
2115            JOptionPane.showMessageDialog(
2116                w,
2117                w.getResourceConverter().getFormattedString(
2118                    "workbench.main.uncoverable_error",
2119                    "Pentaho Schema Workbench has encountered an unrecoverable error. \n{0}",
2120                    ex.getLocalizedMessage()),
2121                w.getResourceConverter().getString(
2122                    "workbench.main.uncoverable_error.title",
2123                    "PSW Fatal Error"),
2124                JOptionPane.ERROR_MESSAGE);
2125            }
2126            LOGGER.error("main", ex);
2127        }
2128    }
2129
2130    // Variables declaration - do not modify
2131    private javax.swing.JButton toolbarSaveAsButton;
2132    private javax.swing.JMenuItem openMenuItem;
2133    private javax.swing.JMenuItem lastUsed1MenuItem;
2134    private javax.swing.JMenuItem lastUsed2MenuItem;
2135    private javax.swing.JMenuItem lastUsed3MenuItem;
2136    private javax.swing.JMenuItem lastUsed4MenuItem;
2137    private javax.swing.JMenu fileMenu;
2138    private javax.swing.JMenuItem newQueryMenuItem;
2139    private javax.swing.JMenuItem newQueryMenuItem2;
2140    private javax.swing.JPanel jPanel1;
2141    private javax.swing.JPanel jPanel2;
2142    private javax.swing.JButton toolbarOpenButton;
2143    private javax.swing.JButton toolbarNewButton;
2144    private javax.swing.JButton toolbarNewArrowButton;
2145    private javax.swing.JSeparator jSeparator1;
2146    private javax.swing.JSeparator jSeparator2;
2147    private javax.swing.JSeparator jSeparator3;
2148    private javax.swing.JMenuItem cutMenuItem;
2149    private javax.swing.JMenuBar menuBar;
2150    private javax.swing.JMenuItem saveMenuItem;
2151    private javax.swing.JMenuItem newJDBCExplorerMenuItem;
2152    private javax.swing.JMenuItem newJDBCExplorerMenuItem2;
2153    private javax.swing.JButton toolbarSaveButton;
2154    private javax.swing.JMenuItem copyMenuItem;
2155    private javax.swing.JDesktopPane desktopPane;
2156    private javax.swing.JMenu viewMenu;
2157    private javax.swing.JMenu toolsMenu;
2158    private javax.swing.JMenu newMenu;
2159    private javax.swing.JMenuItem deleteMenuItem;
2160    private javax.swing.JMenuItem newSchemaMenuItem;
2161    private javax.swing.JMenuItem newSchemaMenuItem2;
2162    private javax.swing.JMenuItem exitMenuItem;
2163    private javax.swing.JButton toolbarPreferencesButton;
2164    private javax.swing.JCheckBoxMenuItem requireSchemaCheckboxMenuItem;
2165    private javax.swing.JMenu editMenu;
2166    private javax.swing.JMenuItem pasteMenuItem;
2167    private javax.swing.JMenuItem preferencesMenuItem;
2168    private javax.swing.JCheckBoxMenuItem viewXmlMenuItem;
2169    private javax.swing.JMenuItem saveAsMenuItem;
2170    private javax.swing.JToolBar jToolBar1;
2171    private javax.swing.JToolBar jToolBar2;
2172    private javax.swing.JPopupMenu toolbarNewPopupMenu;
2173    private javax.swing.JMenu windowMenu;
2174    private javax.swing.JMenu helpMenu;
2175    private javax.swing.JMenuItem aboutMenuItem;
2176    private javax.swing.JMenuItem cascadeMenuItem;
2177    private javax.swing.JMenuItem tileMenuItem;
2178    private javax.swing.JMenuItem minimizeMenuItem;
2179    private javax.swing.JMenuItem maximizeMenuItem;
2180    private javax.swing.JMenuItem closeAllMenuItem;
2181// End of variables declaration
2182
2183    /**
2184     * Used by schema framewhen it uses 'view xml' to update view xml menu item
2185     */
2186    public javax.swing.JCheckBoxMenuItem getViewXmlMenuItem() {
2187        return viewXmlMenuItem;
2188    }
2189}
2190
2191// End Workbench.java