/* // This software is subject to the terms of the Eclipse Public License v1.0 // Agreement, available at the following URL: // http://www.eclipse.org/legal/epl-v10.html. // You must accept the terms of that agreement to use this software. // // Copyright (C) 1999-2005 Julian Hyde // Copyright (C) 2005-2015 Pentaho and others // Copyright (C) 2006-2007 Cincom Systems, Inc. // Copyright (C) 2006-2007 JasperSoft // All Rights Reserved. */ package mondrian.gui; import mondrian.olap.DriverManager; import mondrian.olap.MondrianProperties; import mondrian.olap.Util; import mondrian.olap.Util.PropertyList; import mondrian.server.MondrianServerRegistry; import mondrian.util.UnionIterator; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.apache.log4j.Logger; import org.eigenbase.xom.XMLOutput; import org.eigenbase.xom.*; import org.pentaho.di.core.Const; import org.pentaho.di.core.KettleClientEnvironment; import org.pentaho.di.core.database.DatabaseMeta; import org.pentaho.di.core.exception.KettleDatabaseException; import org.pentaho.di.core.exception.KettleException; import org.pentaho.ui.database.DatabaseConnectionDialog; import org.pentaho.ui.database.Messages; import org.pentaho.ui.database.event.DataHandler; import org.pentaho.ui.xul.*; import org.pentaho.ui.xul.containers.XulDialog; import org.pentaho.ui.xul.swing.SwingXulLoader; import java.awt.*; import java.awt.event.*; import java.io.*; import java.net.*; import java.util.*; import java.util.List; import javax.swing.*; import javax.swing.event.InternalFrameAdapter; import javax.swing.event.InternalFrameEvent; import javax.swing.filechooser.FileSystemView; import javax.swing.plaf.basic.BasicArrowButton; import javax.swing.text.DefaultEditorKit; import javax.swing.tree.TreePath; /** * @author sean */ public class Workbench extends javax.swing.JFrame { private static final long serialVersionUID = 1L; static String WORKBENCH_USER_HOME_DIR; static String WORKBENCH_CONFIG_FILE; static String DB_META_CONFIG_FILE; private static final String LAST_USED1 = "lastUsed1"; private static final String LAST_USED1_URL = "lastUsedUrl1"; private static final String LAST_USED2 = "lastUsed2"; private static final String LAST_USED2_URL = "lastUsedUrl2"; private static final String LAST_USED3 = "lastUsed3"; private static final String LAST_USED3_URL = "lastUsedUrl3"; private static final String LAST_USED4 = "lastUsed4"; private static final String LAST_USED4_URL = "lastUsedUrl4"; private static final String WorkbenchInfoResourceName = "mondrian.gui.resources.workbenchInfo"; private static final String GUIResourceName = "mondrian.gui.resources.gui"; private static final String TextResourceName = "mondrian.gui.resources.text"; private static final String FILTER_SCHEMA_LIST = "FILTER_SCHEMA_LIST"; private static final Logger LOGGER = Logger.getLogger(Workbench.class); private String jdbcDriverClassName; private String jdbcConnectionUrl; private String jdbcUsername; private String jdbcPassword; private String jdbcSchema; private boolean requireSchema; private JdbcMetaData jdbcMetaData; private final ClassLoader myClassLoader; private Properties workbenchProperties; private static ResourceBundle workbenchResourceBundle = null; private static I18n resourceConverter = null; private static int newSchema = 1; private String openFile = null; private Map<JInternalFrame, JMenuItem> schemaWindowMap = new HashMap<JInternalFrame, JMenuItem>(); private final List<JInternalFrame> mdxWindows = new ArrayList<JInternalFrame>(); private final List<JInternalFrame> jdbcWindows = new ArrayList<JInternalFrame>(); private int windowMenuMapIndex = 1; private static final String KETTLE_PLUGIN_BASE_FOLDERS = "kettle-plugins," + "plugins," + Const.getKettleDirectory() + Const.FILE_SEPARATOR + "plugins"; private XulDialog connectionDialog = null; private DataHandler connectionDialogController = null; private DatabaseMeta dbMeta = null; /** * Creates new form Workbench */ public Workbench() { myClassLoader = this.getClass().getClassLoader(); resourceConverter = getGlobalResourceConverter(); // Setting User home directory WORKBENCH_USER_HOME_DIR = System.getProperty("user.home") + File.separator + ".schemaWorkbench"; WORKBENCH_CONFIG_FILE = WORKBENCH_USER_HOME_DIR + File.separator + "workbench.properties"; DB_META_CONFIG_FILE = WORKBENCH_USER_HOME_DIR + File.separator + "databaseMeta.xml"; loadWorkbenchProperties(); loadDatabaseMeta(); initOptions(); initComponents(); loadMenubarPlugins(); ImageIcon icon = new javax.swing.ImageIcon( myClassLoader.getResource( getResourceConverter().getGUIReference("productIcon"))); this.setIconImage(icon.getImage()); } public static I18n getGlobalResourceConverter() { if (resourceConverter == null) { ClassLoader currentClassLoader; ResourceBundle localGuiResourceBundle; ResourceBundle localTextResourceBundle; currentClassLoader = Workbench.class.getClassLoader(); localGuiResourceBundle = ResourceBundle.getBundle( GUIResourceName, Locale.getDefault(), currentClassLoader); localTextResourceBundle = ResourceBundle.getBundle( TextResourceName, Locale.getDefault(), currentClassLoader); resourceConverter = new I18n( localGuiResourceBundle, localTextResourceBundle); } return resourceConverter; } /** * load properties */ private void loadWorkbenchProperties() { workbenchProperties = new Properties(); try { workbenchResourceBundle = ResourceBundle.getBundle( WorkbenchInfoResourceName, Locale.getDefault(), myClassLoader); File f = new File(WORKBENCH_CONFIG_FILE); if (f.exists()) { workbenchProperties.load(new FileInputStream(f)); } else { LOGGER.debug(WORKBENCH_CONFIG_FILE + " does not exist"); } } catch (Exception e) { // TODO deal with exception LOGGER.error("loadWorkbenchProperties", e); } } /** * load database meta */ public void loadDatabaseMeta() { if (dbMeta == null) { File file = new File(DB_META_CONFIG_FILE); if (file.exists()) { try { final String fileContents = FileUtils.readFileToString(file); if (Util.isBlank(fileContents)) { LOGGER.error( "DB Meta file is empty at: " + DB_META_CONFIG_FILE); } else { dbMeta = getDbMeta(fileContents); } } catch (Exception e) { LOGGER.error( "Failed to load DB meta file at: " + DB_META_CONFIG_FILE, e); } } } if (dbMeta != null) { syncToWorkspace(dbMeta); } } /** * returns the value of a workbench property * * @param key key to lookup * @return the value */ public String getWorkbenchProperty(String key) { return workbenchProperties.getProperty(key); } /** * set a workbench property. Note that this does not save the property, * a call to storeWorkbenchProperties is required. * * @param key property key * @param value property value */ public void setWorkbenchProperty(String key, String value) { workbenchProperties.setProperty(key, value); } /** * save properties */ public void storeWorkbenchProperties() { // save properties to file File dir = new File(WORKBENCH_USER_HOME_DIR); try { if (dir.exists()) { if (!dir.isDirectory()) { JOptionPane.showMessageDialog( this, getResourceConverter().getFormattedString( "workbench.user.home.not.directory", "{0} is not a directory!\nPlease rename this file and retry to save configuration!", WORKBENCH_USER_HOME_DIR), "", JOptionPane.ERROR_MESSAGE); return; } } else { dir.mkdirs(); } } catch (Exception ex) { LOGGER.error("storeWorkbenchProperties: mkdirs", ex); JOptionPane.showMessageDialog( this, getResourceConverter().getFormattedString( "workbench.user.home.exception", "An error is occurred creating workbench configuration directory:\n{0}\nError is: {1}", WORKBENCH_USER_HOME_DIR, ex.getLocalizedMessage()), "", JOptionPane.ERROR_MESSAGE); return; } OutputStream out = null; try { out = new FileOutputStream( new File( WORKBENCH_CONFIG_FILE)); workbenchProperties.store(out, "Workbench configuration"); } catch (Exception e) { LOGGER.error("storeWorkbenchProperties: store", e); JOptionPane.showMessageDialog( this, getResourceConverter().getFormattedString( "workbench.save.configuration", "An error is occurred creating workbench configuration file:\n{0}\nError is: {1}", WORKBENCH_CONFIG_FILE, e.getLocalizedMessage()), "", JOptionPane.ERROR_MESSAGE); } finally { try { out.close(); } catch (IOException eIO) { LOGGER.error("storeWorkbenchProperties: out.close", eIO); } } } /** * save database meta */ public void storeDatabaseMeta() { if (dbMeta != null) { try { File file = new File(DB_META_CONFIG_FILE); PrintWriter pw = new PrintWriter(new FileWriter(file)); pw.println(dbMeta.getXML()); pw.close(); } catch (IOException e) { LOGGER.error("storeDatabaseMeta", e); } } } /** * Initialize the UI options */ private void initOptions() { requireSchema = "true".equals(getWorkbenchProperty("requireSchema")); } /** * This method is called from within the constructor to * initialize the form. */ private void initComponents() { desktopPane = new javax.swing.JDesktopPane(); jToolBar1 = new javax.swing.JToolBar(); jToolBar2 = new javax.swing.JToolBar(); toolbarNewPopupMenu = new JPopupMenu(); toolbarNewButton = new javax.swing.JButton(); toolbarOpenButton = new javax.swing.JButton(); toolbarSaveButton = new javax.swing.JButton(); toolbarSaveAsButton = new javax.swing.JButton(); jPanel1 = new javax.swing.JPanel(); jPanel2 = new javax.swing.JPanel(); toolbarPreferencesButton = new javax.swing.JButton(); requireSchemaCheckboxMenuItem = new javax.swing.JCheckBoxMenuItem(); menuBar = new javax.swing.JMenuBar(); fileMenu = new javax.swing.JMenu(); newMenu = new javax.swing.JMenu(); newSchemaMenuItem = new javax.swing.JMenuItem(); newQueryMenuItem = new javax.swing.JMenuItem(); newJDBCExplorerMenuItem = new javax.swing.JMenuItem(); newSchemaMenuItem2 = new javax.swing.JMenuItem(); newQueryMenuItem2 = new javax.swing.JMenuItem(); newJDBCExplorerMenuItem2 = new javax.swing.JMenuItem(); openMenuItem = new javax.swing.JMenuItem(); preferencesMenuItem = new javax.swing.JMenuItem(); lastUsed1MenuItem = new javax.swing.JMenuItem(); lastUsed2MenuItem = new javax.swing.JMenuItem(); lastUsed3MenuItem = new javax.swing.JMenuItem(); lastUsed4MenuItem = new javax.swing.JMenuItem(); saveMenuItem = new javax.swing.JMenuItem(); saveAsMenuItem = new javax.swing.JMenuItem(); jSeparator1 = new javax.swing.JSeparator(); jSeparator2 = new javax.swing.JSeparator(); jSeparator3 = new javax.swing.JSeparator(); exitMenuItem = new javax.swing.JMenuItem(); windowMenu = new javax.swing.JMenu(); helpMenu = new javax.swing.JMenu(); editMenu = new javax.swing.JMenu(); cutMenuItem = new javax.swing.JMenuItem(new DefaultEditorKit.CutAction()); copyMenuItem = new javax.swing.JMenuItem(new DefaultEditorKit.CopyAction()); pasteMenuItem = new javax.swing.JMenuItem(new DefaultEditorKit.PasteAction()); deleteMenuItem = new javax.swing.JMenuItem( new AbstractAction( getResourceConverter().getString( "workbench.menu.delete", "Delete")) { private static final long serialVersionUID = 1L; public void actionPerformed(ActionEvent e) { JInternalFrame jf = desktopPane.getSelectedFrame(); if (jf != null && jf.getContentPane() .getComponent(0) instanceof SchemaExplorer) { SchemaExplorer se = (SchemaExplorer) jf.getContentPane() .getComponent(0); TreePath tpath = se.tree.getSelectionPath(); se.delete(tpath); } } }); aboutMenuItem = new javax.swing.JMenuItem(); toolsMenu = new javax.swing.JMenu(); viewMenu = new javax.swing.JMenu(); viewXmlMenuItem = new javax.swing.JCheckBoxMenuItem(); setTitle( getResourceConverter().getString( "workbench.panel.title", "Schema Workbench")); setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); addWindowListener( new WindowAdapter() { public void windowClosing(WindowEvent evt) { storeWorkbenchProperties(); storeDatabaseMeta(); closeAllSchemaFrames(true); } }); getContentPane().add(desktopPane, java.awt.BorderLayout.CENTER); newSchemaMenuItem2.setText( getResourceConverter().getString( "workbench.menu.newSchema", "Schema")); newSchemaMenuItem2.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent evt) { newSchemaMenuItemActionPerformed(evt); } }); newQueryMenuItem2.setText( getResourceConverter().getString( "workbench.menu.newQuery", "MDX Query")); newQueryMenuItem2.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent evt) { newQueryMenuItemActionPerformed(evt); } }); newJDBCExplorerMenuItem2.setText( getResourceConverter().getString( "workbench.menu.newJDBC", "JDBC Explorer")); newJDBCExplorerMenuItem2.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent evt) { newJDBCExplorerMenuItemActionPerformed(evt); } }); toolbarNewPopupMenu.add(newSchemaMenuItem2); toolbarNewPopupMenu.add(newQueryMenuItem2); toolbarNewPopupMenu.add(newJDBCExplorerMenuItem2); jPanel2.setLayout(new java.awt.BorderLayout()); jPanel2.setBorder(javax.swing.BorderFactory.createEtchedBorder()); jPanel2.setMaximumSize(new java.awt.Dimension(50, 28)); toolbarNewButton.setIcon( new javax.swing.ImageIcon( getClass().getResource( getResourceConverter().getGUIReference("new")))); toolbarNewButton.setToolTipText( getResourceConverter().getString( "workbench.toolbar.new", "New")); toolbarNewButton.setBorderPainted(false); toolbarNewButton.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { toolbarNewPopupMenu.show( jPanel2, 0, jPanel2.getSize().height); } }); jToolBar2.setFloatable(false); jToolBar2.add(toolbarNewButton); jPanel2.add(jToolBar2, java.awt.BorderLayout.CENTER); toolbarNewArrowButton = new BasicArrowButton(SwingConstants.SOUTH); toolbarNewArrowButton.setToolTipText( getResourceConverter().getString( "workbench.toolbar.newArrow", "New")); toolbarNewArrowButton.setBorderPainted(false); toolbarNewArrowButton.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { toolbarNewPopupMenu.show( jPanel2, 0, jPanel2.getSize().height); } }); jPanel2.add(toolbarNewArrowButton, java.awt.BorderLayout.EAST); jToolBar1.add(jPanel2, 0); toolbarOpenButton.setIcon( new javax.swing.ImageIcon( getClass().getResource( getResourceConverter().getGUIReference("open")))); toolbarOpenButton.setToolTipText( getResourceConverter().getString( "workbench.toolbar.open", "Open")); toolbarOpenButton.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent evt) { openMenuItemActionPerformed(evt); } }); jToolBar1.add(toolbarOpenButton); toolbarSaveButton.setIcon( new javax.swing.ImageIcon( getClass().getResource( getResourceConverter().getGUIReference("save")))); toolbarSaveButton.setToolTipText( getResourceConverter().getString( "workbench.toolbar.save", "Save")); toolbarSaveButton.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent evt) { saveMenuItemActionPerformed(evt); } }); jToolBar1.add(toolbarSaveButton); toolbarSaveAsButton.setIcon( new javax.swing.ImageIcon( getClass().getResource( getResourceConverter().getGUIReference("saveAs")))); toolbarSaveAsButton.setToolTipText( getResourceConverter().getString( "workbench.toolbar.saveAs", "Save As")); toolbarSaveAsButton.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent evt) { saveAsMenuItemActionPerformed(evt); } }); jToolBar1.add(toolbarSaveAsButton); jPanel1.setMaximumSize(new java.awt.Dimension(8, 8)); jToolBar1.add(jPanel1); toolbarPreferencesButton.setIcon( new javax.swing.ImageIcon( getClass().getResource( getResourceConverter().getGUIReference("preferences")))); toolbarPreferencesButton.setToolTipText( getResourceConverter().getString( "workbench.toolbar.connection", "Connection")); toolbarPreferencesButton.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent evt) { connectionButtonActionPerformed(evt); } }); jToolBar1.add(toolbarPreferencesButton); getContentPane().add(jToolBar1, java.awt.BorderLayout.NORTH); fileMenu.setText( getResourceConverter().getString( "workbench.menu.file", "File")); fileMenu.setMnemonic(KeyEvent.VK_F); newMenu.setText( getResourceConverter().getString( "workbench.menu.new", "New")); newSchemaMenuItem.setText( getResourceConverter().getString( "workbench.menu.newSchema", "Schema")); newSchemaMenuItem.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent evt) { newSchemaMenuItemActionPerformed(evt); } }); newMenu.add(newSchemaMenuItem); newQueryMenuItem.setText( getResourceConverter().getString( "workbench.menu.newQuery", "MDX Query")); newQueryMenuItem.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent evt) { newQueryMenuItemActionPerformed(evt); } }); newMenu.add(newQueryMenuItem); newJDBCExplorerMenuItem.setText( getResourceConverter().getString( "workbench.menu.newJDBC", "JDBC Explorer")); newJDBCExplorerMenuItem.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent evt) { newJDBCExplorerMenuItemActionPerformed(evt); } }); newMenu.add(newJDBCExplorerMenuItem); fileMenu.add(newMenu); openMenuItem.setText( getResourceConverter().getString( "workbench.menu.open", "Open")); openMenuItem.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent evt) { openMenuItemActionPerformed(evt); } }); fileMenu.add(openMenuItem); saveMenuItem.setText( getResourceConverter().getString( "workbench.menu.save", "Save")); saveMenuItem.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent evt) { saveMenuItemActionPerformed(evt); } }); fileMenu.add(saveMenuItem); saveAsMenuItem.setText( getResourceConverter().getString( "workbench.menu.saveAsDot", "Save As ...")); saveAsMenuItem.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent evt) { saveAsMenuItemActionPerformed(evt); } }); fileMenu.add(saveAsMenuItem); // add last used fileMenu.add(jSeparator2); lastUsed1MenuItem.setText(getWorkbenchProperty("lastUsed1")); lastUsed1MenuItem.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent evt) { lastUsed1MenuItemActionPerformed(evt); } }); fileMenu.add(lastUsed1MenuItem); lastUsed2MenuItem.setText(getWorkbenchProperty("lastUsed2")); lastUsed2MenuItem.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent evt) { lastUsed2MenuItemActionPerformed(evt); } }); fileMenu.add(lastUsed2MenuItem); lastUsed3MenuItem.setText(getWorkbenchProperty("lastUsed3")); lastUsed3MenuItem.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent evt) { lastUsed3MenuItemActionPerformed(evt); } }); fileMenu.add(lastUsed3MenuItem); lastUsed4MenuItem.setText(getWorkbenchProperty("lastUsed4")); lastUsed4MenuItem.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent evt) { lastUsed4MenuItemActionPerformed(evt); } }); fileMenu.add(lastUsed4MenuItem); updateLastUsedMenu(); fileMenu.add(jSeparator1); exitMenuItem.setText( getResourceConverter().getString( "workbench.menu.exit", "Exit")); exitMenuItem.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent evt) { exitMenuItemActionPerformed(evt); } }); fileMenu.add(exitMenuItem); menuBar.add(fileMenu); editMenu.setText( getResourceConverter().getString( "workbench.menu.edit", "Edit")); editMenu.setMnemonic(KeyEvent.VK_E); cutMenuItem.setText( getResourceConverter().getString( "workbench.menu.cut", "Cut")); editMenu.add(cutMenuItem); copyMenuItem.setText( getResourceConverter().getString( "workbench.menu.copy", "Copy")); editMenu.add(copyMenuItem); pasteMenuItem.setText( getResourceConverter().getString( "workbench.menu.paste", "Paste")); editMenu.add(pasteMenuItem); editMenu.add(deleteMenuItem); menuBar.add(editMenu); viewMenu.setText( getResourceConverter().getString( "workbench.menu.view", "View")); viewMenu.setMnemonic(KeyEvent.VK_V); viewXmlMenuItem.setText( getResourceConverter().getString( "workbench.menu.viewXML", "View XML")); viewXmlMenuItem.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent evt) { viewXMLMenuItemActionPerformed(evt); } }); viewMenu.add(viewXmlMenuItem); menuBar.add(viewMenu); toolsMenu.setText(getResourceConverter().getString( "workbench.menu.options", "Options")); toolsMenu.setMnemonic(KeyEvent.VK_O); preferencesMenuItem.setText(getResourceConverter().getString( "workbench.menu.connection", "Connection")); preferencesMenuItem.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent evt) { connectionButtonActionPerformed(evt); } }); toolsMenu.add(preferencesMenuItem); requireSchemaCheckboxMenuItem.setText( getResourceConverter().getString( "workbench.menu.requireSchema", "Require Schema")); requireSchemaCheckboxMenuItem.setSelected(requireSchema); requireSchemaCheckboxMenuItem.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { requireSchemaActionPerformed(e); } }); toolsMenu.add(requireSchemaCheckboxMenuItem); menuBar.add(toolsMenu); windowMenu.setText( getResourceConverter().getString( "workbench.menu.windows", "Windows")); windowMenu.setMnemonic(KeyEvent.VK_W); cascadeMenuItem = new javax.swing.JMenuItem(); cascadeMenuItem.setText( getResourceConverter().getString( "workbench.menu.cascadeWindows", "Cascade Windows")); cascadeMenuItem.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent evt) { cascadeMenuItemActionPerformed(evt); } }); tileMenuItem = new javax.swing.JMenuItem(); tileMenuItem.setText( getResourceConverter().getString( "workbench.menu.tileWindows", "Tile Windows")); tileMenuItem.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent evt) { tileMenuItemActionPerformed(evt); } }); closeAllMenuItem = new javax.swing.JMenuItem(); closeAllMenuItem.setText( getResourceConverter().getString( "workbench.menu.closeAll", "Close All")); closeAllMenuItem.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent evt) { closeAllMenuItemActionPerformed(evt); } }); minimizeMenuItem = new javax.swing.JMenuItem(); minimizeMenuItem.setText( getResourceConverter().getString( "workbench.menu.minimizeAll", "Minimize All")); minimizeMenuItem.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent evt) { minimizeMenuItemActionPerformed(evt); } }); maximizeMenuItem = new javax.swing.JMenuItem(); maximizeMenuItem.setText( getResourceConverter().getString( "workbench.menu.maximizeAll", "Maximize All")); maximizeMenuItem.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent evt) { maximizeMenuItemActionPerformed(evt); } }); menuBar.add(windowMenu); aboutMenuItem.setText( getResourceConverter().getString( "workbench.menu.about", "About")); aboutMenuItem.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent evt) { aboutMenuItemActionPerformed(evt); } }); helpMenu.add(aboutMenuItem); helpMenu.setText( getResourceConverter().getString( "workbench.menu.help", "Help")); helpMenu.setMnemonic(KeyEvent.VK_H); menuBar.add(helpMenu); setJMenuBar(menuBar); pack(); } /** * this method loads any available menubar plugins based on */ private void loadMenubarPlugins() { // render any plugins InputStream pluginStream = null; try { Properties props = new Properties(); pluginStream = getClass().getResourceAsStream( "/workbench_plugins.properties"); if (pluginStream != null) { props.load(pluginStream); for (Object key : props.keySet()) { String keystr = (String) key; if (keystr.startsWith("workbench.menu-plugin")) { String val = props.getProperty(keystr); WorkbenchMenubarPlugin plugin = (WorkbenchMenubarPlugin) Class.forName(val) .newInstance(); plugin.setWorkbench(this); plugin.addItemsToMenubar(menuBar); } } } } catch (Exception e) { e.printStackTrace(); } finally { try { if (pluginStream != null) { pluginStream.close(); } } catch (Exception e) { } } } /** * @return the workbenchResourceBundle */ public ResourceBundle getWorkbenchResourceBundle() { return workbenchResourceBundle; } /** * @return the resourceConverter */ public I18n getResourceConverter() { if (resourceConverter == null) { resourceConverter = getGlobalResourceConverter(); } return resourceConverter; } private void tileMenuItemActionPerformed(ActionEvent evt) { final Dimension dsize = desktopPane.getSize(); final int desktopW = (int) dsize.getWidth(); final int desktopH = (int) dsize.getHeight(); final int darea = desktopW * desktopH; final double eacharea = darea / (schemaWindowMap.size() + mdxWindows.size() + jdbcWindows.size()); final int wh = (int) Math.sqrt(eacharea); try { int x = 0, y = 0; for (JInternalFrame sf : getAllFrames()) { if (sf != null && !sf.isIcon()) { sf.setMaximum(false); sf.moveToFront(); if (x >= desktopW || (desktopW - x) * wh < eacharea / 2) { // move to next row of windows y += wh; x = 0; } int sfwidth = ((x + wh) < desktopW ? wh : desktopW - x); int sfheight = ((y + wh) < desktopH ? wh : desktopH - y); sf.setBounds(x, y, sfwidth, sfheight); x += sfwidth; } } } catch (Exception ex) { LOGGER.error("tileMenuItemActionPerformed", ex); // do nothing } } // cascade all the indows open in schema workbench private void cascadeMenuItemActionPerformed( ActionEvent evt) { try { int sfi = 1; for (JInternalFrame sf : getAllFrames()) { if (sf != null && !sf.isIcon()) { sf.setMaximum(false); sf.setLocation(30 * sfi, 30 * sfi); sf.moveToFront(); sf.setSelected(true); sfi++; } } } catch (Exception ex) { LOGGER.error("cascadeMenuItemActionPerformed", ex); // do nothing } } // close all the windows open in schema workbench private void closeAllMenuItemActionPerformed(ActionEvent evt) { closeAllSchemaFrames(false); } private void closeAllSchemaFrames(boolean exitAfterClose) { try { for (JInternalFrame sf : getAllFrames()) { if (sf == null) { continue; } if (sf.getContentPane().getComponent(0) instanceof SchemaExplorer) { SchemaExplorer se = (SchemaExplorer) sf.getContentPane().getComponent(0); sf.setSelected(true); int response = confirmFrameClose(sf, se); switch (response) { case 2: // cancel return; case 3: // not dirty sf.setClosed(true); break; } } else { sf.setClosed(true); } } // exit Schema Workbench if no files are open if (((schemaWindowMap.keySet().size()) == 0) && exitAfterClose) { System.exit(0); } } catch (Exception ex) { LOGGER.error("closeAllSchemaFrames", ex); } } private int confirmFrameClose( JInternalFrame schemaFrame, SchemaExplorer se) { if (se.isDirty()) { JMenuItem schemaMenuItem = schemaWindowMap.get( desktopPane.getSelectedFrame()); // yes=0; no=1; cancel=2 int answer = JOptionPane.showConfirmDialog( null, getResourceConverter().getFormattedString( "workbench.saveSchemaOnClose.alert", "Save changes to {0}?", se.getSchemaFile().toString()), getResourceConverter().getString( "workbench.saveSchemaOnClose.title", "Schema"), JOptionPane.YES_NO_CANCEL_OPTION); switch (answer) { case 0: saveMenuItemActionPerformed(null); schemaWindowMap.remove(schemaFrame); updateMDXCatalogList(); schemaFrame.dispose(); windowMenu.remove(schemaMenuItem); break; case 1: schemaFrame.dispose(); schemaWindowMap.remove(schemaFrame); windowMenu.remove(schemaMenuItem); break; case 2: try { schemaFrame.setClosed(false); schemaFrame.show(); } catch (Exception ex) { LOGGER.error(ex); } } return answer; } return 3; } private void minimizeMenuItemActionPerformed( ActionEvent evt) { try { for (JInternalFrame sf : getAllFrames()) { if (sf != null && !sf.isIcon()) { sf.setIcon(true); } } } catch (Exception ex) { LOGGER.error("minimizeMenuItemActionPerformed", ex); // do nothing } } private void maximizeMenuItemActionPerformed( ActionEvent evt) { try { for (JInternalFrame sf : getAllFrames()) { if (sf != null) { sf.setIcon(false); sf.setMaximum(true); } } } catch (Exception ex) { LOGGER.error("maximizeMenuItemActionPerformed", ex); // do nothing } } /** * Returns an iterable over all internal frames. */ @SuppressWarnings("unchecked") private Iterable<JInternalFrame> getAllFrames() { return UnionIterator.over( schemaWindowMap.keySet(), mdxWindows, jdbcWindows); } private void aboutMenuItemActionPerformed(ActionEvent evt) { try { URL versionUrl = myClassLoader.getResource( getResourceConverter().getGUIReference("version")); InputStream versionIn = versionUrl.openStream(); String ver = IOUtils.toString(versionIn); ver = ver.replace( "PRODUCT_VERSION", MondrianServerRegistry.INSTANCE.getProductVersion()); ver = ver.replace( "COPYRIGHT_YEAR", MondrianServerRegistry.INSTANCE.getCopyrightYear()); JEditorPane jEditorPane = new JEditorPane("text/html", ver); jEditorPane.setEditable(false); JScrollPane jScrollPane = new JScrollPane(jEditorPane); JPanel jPanel = new JPanel(); jPanel.setLayout(new java.awt.BorderLayout()); jPanel.add(jScrollPane, java.awt.BorderLayout.CENTER); JInternalFrame jf = new JInternalFrame(); jf.setTitle("About"); jf.getContentPane().add(jPanel); Dimension screenSize = this.getSize(); int aboutW = 400; int aboutH = 300; int width = (screenSize.width / 2) - (aboutW / 2); int height = (screenSize.height / 2) - (aboutH / 2) - 100; jf.setBounds(width, height, aboutW, aboutH); jf.setClosable(true); desktopPane.add(jf); jf.setVisible(true); jf.show(); } catch (Exception ex) { LOGGER.error("aboutMenuItemActionPerformed", ex); } } private void newJDBCExplorerMenuItemActionPerformed( ActionEvent evt) { try { if (jdbcMetaData == null) { getNewJdbcMetadata(); } final JInternalFrame jf = new JInternalFrame(); jf.setTitle( getResourceConverter().getFormattedString( "workbench.new.JDBCExplorer.title", "JDBC Explorer - {0} {1}", jdbcMetaData.getDatabaseProductName(), jdbcMetaData.getJdbcConnectionUrl())); getNewJdbcMetadata(); JdbcExplorer jdbce = new JdbcExplorer(jdbcMetaData, this); jf.getContentPane().add(jdbce); jf.setBounds(0, 0, 500, 480); jf.setClosable(true); jf.setIconifiable(true); jf.setMaximizable(true); jf.setResizable(true); jf.setVisible(true); // create jdbc menu item final javax.swing.JMenuItem jdbcMenuItem = new javax.swing.JMenuItem(); jdbcMenuItem.setText( getResourceConverter().getFormattedString( "workbench.new.JDBCExplorer.menuitem", "{0} JDBC Explorer", Integer.toString(windowMenuMapIndex++))); jdbcMenuItem.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent evt) { try { if (jf.isIcon()) { jf.setIcon(false); } else { jf.setSelected(true); } } catch (Exception ex) { LOGGER.error("queryMenuItem", ex); } } }); jf.addInternalFrameListener( new InternalFrameAdapter() { public void internalFrameClosing(InternalFrameEvent e) { jdbcWindows.remove(jf); jf.dispose(); // follow this by removing file from schemaWindowMap windowMenu.remove(jdbcMenuItem); return; } }); desktopPane.add(jf); jf.setVisible(true); jf.show(); try { jf.setSelected(true); } catch (Exception ex) { // do nothing LOGGER.error( "newJDBCExplorerMenuItemActionPerformed.setSelected", ex); } jdbcWindows.add(jf); windowMenu.add(jdbcMenuItem, -1); windowMenu.add(jSeparator3, -1); windowMenu.add(cascadeMenuItem, -1); windowMenu.add(tileMenuItem, -1); windowMenu.add(minimizeMenuItem, -1); windowMenu.add(maximizeMenuItem, -1); windowMenu.add(closeAllMenuItem, -1); } catch (Exception ex) { JOptionPane.showMessageDialog( this, getResourceConverter().getFormattedString( "workbench.new.JDBCExplorer.exception", "Database connection not successful.\n{0}", ex.getLocalizedMessage()), getResourceConverter().getString( "workbench.new.JDBCExplorer.exception.title", "Database Connection Error"), JOptionPane.ERROR_MESSAGE); LOGGER.error("newJDBCExplorerMenuItemActionPerformed", ex); } } /** * Convenience method for retrieving the dbMeta instance that handles * required Kettle initialization. * * @param xml output of {@link DatabaseMeta#getXML()} or <code>null</code> * @return the current {@link DatabaseMeta} instance */ private DatabaseMeta getDbMeta(String xml) { try { if (!KettleClientEnvironment.isInitialized()) { System.setProperty( "KETTLE_PLUGIN_BASE_FOLDERS", KETTLE_PLUGIN_BASE_FOLDERS); KettleClientEnvironment.init(); } if (dbMeta != null) { return dbMeta; } if (xml == null) { dbMeta = new DatabaseMeta(); } else { dbMeta = new DatabaseMeta(xml); } } catch (KettleException e) { throw new RuntimeException( getResourceConverter().getFormattedString( "workbench.new.Kettle.exception", "Kettle failed to initialize."), e); } return dbMeta; } private void connectionButtonActionPerformed(ActionEvent evt) { if (connectionDialog == null) { dbMeta = getDbMeta(null); connectionDialogController = new DataHandler(); connectionDialogController.setName("dataHandler"); XulDomContainer container = null; try { XulLoader loader = new SwingXulLoader(); container = loader.loadXul( DatabaseConnectionDialog.DIALOG_DEFINITION_FILE, Messages.getBundle()); } catch (XulException e) { throw new RuntimeException("Xul failed to initialize", e); } container.addEventHandler(connectionDialogController); connectionDialogController.loadConnectionData(); connectionDialogController.setData(dbMeta); connectionDialog = (XulDialog) container.getDocumentRoot() .getRootElement(); } connectionDialog.show(); dbMeta = (DatabaseMeta) connectionDialogController.getData(); if (dbMeta.hasChanged()) { dbMeta.clearChanged(); syncToWorkspace(dbMeta); // Enforces the JDBC preferences entered throughout all schemas // currently opened in the workbench. resetWorkbench(); } } private void syncToWorkspace(DatabaseMeta databaseMeta) { // sync from dbmeta to wkspc try { jdbcConnectionUrl = databaseMeta.getURL(); } catch (KettleDatabaseException e) { throw new RuntimeException("Failed to determine JDBC URL", e); } jdbcDriverClassName = databaseMeta.getDriverClass(); jdbcUsername = databaseMeta.getUsername(); jdbcPassword = databaseMeta.getPassword(); //jdbcSchema = databaseMeta.getPreferredSchemaName(); Map<String, String> options = dbMeta.getExtraOptions(); String dbType = dbMeta.getDatabaseInterface().getPluginId(); jdbcSchema = options.get(dbType + "." + FILTER_SCHEMA_LIST); // saving to workbench properties for documentation purposes only, since // persistence // of the dbmeta object is handled by a separate xml file now if (jdbcDriverClassName != null) { setWorkbenchProperty("jdbcDriverClassName", jdbcDriverClassName); } if (jdbcConnectionUrl != null) { setWorkbenchProperty("jdbcConnectionUrl", jdbcConnectionUrl); } if (jdbcUsername != null) { setWorkbenchProperty("jdbcUsername", jdbcUsername); } if (jdbcPassword != null) { setWorkbenchProperty("jdbcPassword", jdbcPassword); } if (jdbcSchema != null) { setWorkbenchProperty("jdbcSchema", jdbcSchema); } } private void requireSchemaActionPerformed(ActionEvent evt) { requireSchema = ((JCheckBoxMenuItem) evt.getSource()).isSelected(); setWorkbenchProperty("requireSchema", "" + requireSchema); } private void newSchemaMenuItemActionPerformed(ActionEvent evt) { MondrianProperties.instance(); // User's default directory. This default depends on the operating // system. It is typically the "My Documents" folder on Windows, and // the user's home directory on Unix. File defaultDir = FileSystemView.getFileSystemView().getDefaultDirectory(); File outputFile; do { outputFile = new File(defaultDir, "Schema" + newSchema++ + ".xml"); } while (outputFile.exists()); openSchemaFrame(outputFile, true); } private void newQueryMenuItemActionPerformed(ActionEvent evt) { JMenuItem schemaMenuItem = schemaWindowMap.get(desktopPane.getSelectedFrame()); final JInternalFrame jf = new JInternalFrame(); jf.setTitle( getResourceConverter().getString( "workbench.new.MDXQuery.title", "MDX Query")); QueryPanel qp = new QueryPanel(this); jf.getContentPane().add(qp); jf.setBounds(0, 0, 500, 480); jf.setClosable(true); jf.setIconifiable(true); jf.setMaximizable(true); jf.setResizable(true); jf.setVisible(true); desktopPane.add(jf); jf.show(); try { jf.setSelected(true); } catch (Exception ex) { // do nothing LOGGER.error("newQueryMenuItemActionPerformed.setSelected", ex); } // add the mdx frame to this set of mdx frames for cascading method mdxWindows.add(jf); // create mdx menu item final javax.swing.JMenuItem queryMenuItem = new javax.swing.JMenuItem(); queryMenuItem.setText( getResourceConverter().getFormattedString( "workbench.new.MDXQuery.menuitem", "{0} MDX", Integer.toString(windowMenuMapIndex))); queryMenuItem.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent evt) { try { if (jf.isIcon()) { jf.setIcon(false); } else { jf.setSelected(true); } } catch (Exception ex) { LOGGER.error("queryMenuItem", ex); } } }); // disable mdx frame close operation to provide our handler // to remove frame object from mdxframeset before closing jf.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); jf.addInternalFrameListener( new InternalFrameAdapter() { public void internalFrameClosing(InternalFrameEvent e) { mdxWindows.remove(jf); jf.dispose(); // follow this by removing file from schemaWindowMap windowMenu.remove(queryMenuItem); return; } }); windowMenu.add(queryMenuItem, -1); windowMenu.add(jSeparator3, -1); windowMenu.add(cascadeMenuItem, -1); windowMenu.add(tileMenuItem, -1); windowMenu.add(minimizeMenuItem, -1); windowMenu.add(maximizeMenuItem, -1); windowMenu.add(closeAllMenuItem, -1); qp.setMenuItem(queryMenuItem); qp.setSchemaWindowMap(schemaWindowMap); qp.setWindowMenuIndex(windowMenuMapIndex++); if (schemaMenuItem != null) { qp.initConnection(schemaMenuItem.getText()); } else { JOptionPane.showMessageDialog( this, getResourceConverter().getString( "workbench.new.MDXQuery.no.selection", "No Mondrian connection. Select a Schema to connect."), getResourceConverter().getString( "workbench.new.MDXQuery.no.selection.title", "Alert"), JOptionPane.WARNING_MESSAGE); } } // inform all opened mdx query windows about the list of opened schema files private void updateMDXCatalogList() { Iterator<JInternalFrame> it = mdxWindows.iterator(); while (it.hasNext()) { JInternalFrame elem = it.next(); QueryPanel qp = (QueryPanel) elem.getContentPane().getComponent(0); qp.setSchemaWindowMap(schemaWindowMap); } } /** * returns the currently selected schema explorer object * * @return current schema explorer object */ public SchemaExplorer getCurrentSchemaExplorer() { JInternalFrame jf = desktopPane.getSelectedFrame(); if (jf != null && jf.getContentPane().getComponentCount() > 0 && jf .getContentPane().getComponent(0) instanceof SchemaExplorer) { return (SchemaExplorer) jf.getContentPane().getComponent(0); } return null; } private void saveAsMenuItemActionPerformed(ActionEvent evt) { JInternalFrame jf = desktopPane.getSelectedFrame(); if (jf != null && jf.getContentPane() .getComponent(0) instanceof SchemaExplorer) { SchemaExplorer se = (SchemaExplorer) jf.getContentPane().getComponent(0); java.io.File schemaFile = se.getSchemaFile(); java.io.File oldSchemaFile = schemaFile; java.io.File suggSchemaFile = new File( schemaFile == null ? se.getSchema().name.trim() + ".xml" : schemaFile.getName()); MondrianGuiDef.Schema schema = se.getSchema(); JFileChooser jfc = new JFileChooser(); MondrianProperties.instance(); jfc.setSelectedFile(suggSchemaFile); if (!isSchemaValid(schema)) { // the schema would not be re-loadable. Abort save. return; } if (jfc.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) { try { schemaFile = jfc.getSelectedFile(); if (!oldSchemaFile.equals(schemaFile) && schemaFile .exists()) { // new file already exists, check for overwrite int answer = JOptionPane.showConfirmDialog( null, getResourceConverter().getFormattedString( "workbench.saveAs.schema.confirm", "{0} schema file already exists. Do you want to replace it?", schemaFile.getAbsolutePath()), getResourceConverter().getString( "workbench.saveAs.schema.confirm.title", "Save As"), JOptionPane.YES_NO_OPTION); if (answer == 1) { // no=1 ; yes=0 return; } } if (se.isNewFile() && !oldSchemaFile.equals(schemaFile)) { oldSchemaFile.delete(); } if (se.isNewFile()) { se.setNewFile(false); } se.setDirty(false); se.setDirtyFlag(false); XMLOutput out = new XMLOutput( new java.io.FileWriter(jfc.getSelectedFile())); out.setAlwaysQuoteCData(true); out.setIndentString(" "); schema.displayXML(out); se.setSchemaFile(schemaFile); se.setTitle(); // sets title of iframe setLastUsed( jfc.getSelectedFile().getName(), jfc.getSelectedFile().toURI().toURL().toString()); // Update menu item with new file name, then update catalog // list for mdx queries JMenuItem sMenuItem = schemaWindowMap.get(jf); String mtexttokens[] = sMenuItem.getText().split(" "); sMenuItem.setText( mtexttokens[0] + " " + se.getSchemaFile().getName()); // Schema menu item updated, now update mdx query windows // with updated catalog list. updateMDXCatalogList(); } catch (Exception ex) { LOGGER.error(ex); } } } } /** * Validates that the schema can be parsed and loaded, * showing a warning message if any errors are encountered. */ private boolean isSchemaValid(MondrianGuiDef.Schema schema) { try { StringWriter writer = new StringWriter(); XMLOutput xmlOutput = new XMLOutput(writer); schema.displayXML(xmlOutput); Parser xmlParser = XOMUtil.createDefaultParser(); Reader reader = new StringReader(writer.getBuffer().toString()); // attempt to create a new schema new MondrianGuiDef.Schema(xmlParser.parse(reader)); } catch (XOMException e) { JOptionPane.showMessageDialog( this, getResourceConverter().getFormattedString( "workbench.save.invalid.schema", "Please correct the following error before saving:", e.getLocalizedMessage()), getResourceConverter().getFormattedString( "workbench.save.invalid.schema.title", "Cannot Save"), JOptionPane.WARNING_MESSAGE); return false; } return true; } private void viewXMLMenuItemActionPerformed(ActionEvent evt) { JInternalFrame jf = desktopPane.getSelectedFrame(); boolean oldValue = viewXmlMenuItem.getState(); if (jf != null && jf.getContentPane().getComponent(0) instanceof SchemaExplorer) { SchemaExplorer se = (SchemaExplorer) jf.getContentPane().getComponent(0); // Call schema explorer's view xml event and update the workbench's // view menu accordingly' ((JCheckBoxMenuItem) evt.getSource()).setSelected(se.editMode(evt)); return; } viewXmlMenuItem.setSelected(!oldValue); } public void saveMenuItemActionPerformed(ActionEvent evt) { JInternalFrame jf = desktopPane.getSelectedFrame(); // Don't save if nothing there if (jf == null || jf.getContentPane() == null) { return; } if (jf.getContentPane().getComponent(0) instanceof SchemaExplorer) { SchemaExplorer se = (SchemaExplorer) jf.getContentPane().getComponent(0); java.io.File schemaFile = se.getSchemaFile(); if (se.isNewFile()) { saveAsMenuItemActionPerformed(evt); return; } se.setDirty(false); se.setDirtyFlag(false); se.setTitle(); // sets title of iframe MondrianGuiDef.Schema schema = se.getSchema(); if (!isSchemaValid(schema)) { // the schema would not be re-loadable. Abort save. return; } MondrianProperties.instance(); try { XMLOutput out = new XMLOutput(new FileWriter(schemaFile)); out.setAlwaysQuoteCData(true); out.setIndentString(" "); schema.displayXML(out); setLastUsed( schemaFile.getName(), schemaFile.toURI().toURL().toString()); } catch (Exception ex) { LOGGER.error("saveMenuItemActionPerformed", ex); } } } /** * Set last used in properties file */ private void setLastUsed(String name, String url) { int match = 4; String luName = null; String propname = null; String lastUsed = "lastUsed"; String lastUsedUrl = "lastUsedUrl"; for (int i = 1; i <= 4; i++) { propname = lastUsed + i; luName = getWorkbenchProperty(propname); if (luName != null && luName.equals(name)) { match = i; break; } } for (int i = match; i > 1; i--) { if (getWorkbenchProperty(lastUsed + (i - 1)) != null) { setWorkbenchProperty( lastUsed + i, getWorkbenchProperty( lastUsed + (i - 1))); setWorkbenchProperty( lastUsedUrl + i, getWorkbenchProperty( lastUsedUrl + (i - 1))); } } setWorkbenchProperty(LAST_USED1, name); setWorkbenchProperty(LAST_USED1_URL, url); updateLastUsedMenu(); storeWorkbenchProperties(); storeDatabaseMeta(); } private void updateLastUsedMenu() { if (getWorkbenchProperty(LAST_USED1) == null) { jSeparator2.setVisible(false); } else { jSeparator2.setVisible(true); } if (getWorkbenchProperty(LAST_USED1) != null) { lastUsed1MenuItem.setVisible(true); } else { lastUsed1MenuItem.setVisible(false); } if (getWorkbenchProperty(LAST_USED2) != null) { lastUsed2MenuItem.setVisible(true); } else { lastUsed2MenuItem.setVisible(false); } if (getWorkbenchProperty(LAST_USED3) != null) { lastUsed3MenuItem.setVisible(true); } else { lastUsed3MenuItem.setVisible(false); } if (getWorkbenchProperty(LAST_USED4) != null) { lastUsed4MenuItem.setVisible(true); } else { lastUsed4MenuItem.setVisible(false); } lastUsed1MenuItem.setText(getWorkbenchProperty(LAST_USED1)); lastUsed2MenuItem.setText(getWorkbenchProperty(LAST_USED2)); lastUsed3MenuItem.setText(getWorkbenchProperty(LAST_USED3)); lastUsed4MenuItem.setText(getWorkbenchProperty(LAST_USED4)); } private void lastUsed1MenuItemActionPerformed(ActionEvent evt) { try { openSchemaFrame( new File(new URI(getWorkbenchProperty(LAST_USED1_URL))), false); } catch (Exception e) { // probably URISyntaxException LOGGER.error("lastUsed1MenuItemActionPerformed", e); } } private void lastUsed2MenuItemActionPerformed(ActionEvent evt) { try { openSchemaFrame( new File(new URI(getWorkbenchProperty(LAST_USED2_URL))), false); setLastUsed( getWorkbenchProperty(LAST_USED2), getWorkbenchProperty( LAST_USED2_URL)); } catch (URISyntaxException e) { LOGGER.error("lastUsed2MenuItemActionPerformed", e); } } private void lastUsed3MenuItemActionPerformed(ActionEvent evt) { try { openSchemaFrame( new File(new URI(getWorkbenchProperty(LAST_USED3_URL))), false); setLastUsed( getWorkbenchProperty(LAST_USED3), getWorkbenchProperty( LAST_USED3_URL)); } catch (URISyntaxException e) { LOGGER.error("lastUsed3MenuItemActionPerformed", e); } } private void lastUsed4MenuItemActionPerformed(ActionEvent evt) { try { openSchemaFrame( new File(new URI(getWorkbenchProperty(LAST_USED4_URL))), false); setLastUsed( getWorkbenchProperty(LAST_USED4), getWorkbenchProperty( LAST_USED4_URL)); } catch (URISyntaxException e) { LOGGER.error("lastUsed4MenuItemActionPerformed", e); } } private void openSchemaFrame(File file, boolean newFile) { try { setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); if (!newFile) { // check if file not already open if (checkFileOpen(file)) { return; } // check if schema file exists if (!file.exists()) { JOptionPane.showMessageDialog( this, getResourceConverter().getFormattedString( "workbench.open.schema.not.found", "{0} File not found.", file.getAbsolutePath()), getResourceConverter().getString( "workbench.open.schema.not.found.title", "Alert"), JOptionPane.WARNING_MESSAGE); return; } // check if file is writable if (!file.canWrite()) { JOptionPane.showMessageDialog( this, getResourceConverter().getFormattedString( "workbench.open.schema.not.writeable", "{0} is not writeable.", file.getAbsolutePath()), getResourceConverter().getString( "workbench.open.schema.not.writeable.title", "Alert"), JOptionPane.WARNING_MESSAGE); return; } checkSchemaFile(file); } final JInternalFrame schemaFrame = new JInternalFrame(); schemaFrame.setTitle( getResourceConverter().getFormattedString( "workbench.open.schema.title", "Schema - {0}", file.getName())); getNewJdbcMetadata(); schemaFrame.getContentPane().add( new SchemaExplorer( this, file, jdbcMetaData, newFile, schemaFrame)); String errorOpening = ((SchemaExplorer) schemaFrame.getContentPane().getComponent(0)) .getErrMsg(); if (errorOpening != null) { JOptionPane.showMessageDialog( this, getResourceConverter().getFormattedString( "workbench.open.schema.error", "Error opening schema - {0}.", errorOpening), getResourceConverter().getString( "workbench.open.schema.error.title", "Error"), JOptionPane.ERROR_MESSAGE); schemaFrame.setClosed(true); return; } schemaFrame.setBounds(0, 0, 1000, 650); schemaFrame.setClosable(true); schemaFrame.setIconifiable(true); schemaFrame.setMaximizable(true); schemaFrame.setResizable(true); schemaFrame.setVisible(true); desktopPane.add( schemaFrame, javax.swing.JLayeredPane.DEFAULT_LAYER); schemaFrame.show(); schemaFrame.setMaximum(true); displayWarningOnFailedConnection(); final javax.swing.JMenuItem schemaMenuItem = new javax.swing.JMenuItem(); schemaMenuItem.setText(windowMenuMapIndex++ + " " + file.getName()); schemaMenuItem.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent evt) { try { if (schemaFrame.isIcon()) { schemaFrame.setIcon(false); } else { schemaFrame.setSelected(true); } } catch (Exception ex) { LOGGER.error("schemaMenuItem", ex); } } }); windowMenu.add(schemaMenuItem, 0); windowMenu.setEnabled(true); windowMenu.add(jSeparator3, -1); windowMenu.add(cascadeMenuItem, -1); windowMenu.add(tileMenuItem, -1); windowMenu.add(minimizeMenuItem, -1); windowMenu.add(maximizeMenuItem, -1); windowMenu.add(closeAllMenuItem, -1); // add the file details in menu map schemaWindowMap.put(schemaFrame, schemaMenuItem); updateMDXCatalogList(); schemaFrame.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); schemaFrame.addInternalFrameListener( new InternalFrameAdapter() { public void internalFrameClosing(InternalFrameEvent e) { if (schemaFrame.getContentPane() .getComponent(0) instanceof SchemaExplorer) { SchemaExplorer se = (SchemaExplorer) schemaFrame.getContentPane() .getComponent(0); int response = confirmFrameClose(schemaFrame, se); if (response == 3) { // not dirty if (se.isNewFile()) { se.getSchemaFile().delete(); } // default case for no save and not dirty schemaWindowMap.remove(schemaFrame); updateMDXCatalogList(); schemaFrame.dispose(); windowMenu.remove(schemaMenuItem); } } } }); schemaFrame.setFocusable(true); schemaFrame.addFocusListener( new FocusAdapter() { public void focusGained(FocusEvent e) { if (schemaFrame.getContentPane() .getComponent(0) instanceof SchemaExplorer) { SchemaExplorer se = (SchemaExplorer) schemaFrame.getContentPane().getComponent(0); // update view menu based on schemaframe who gained // focus viewXmlMenuItem.setSelected( se.isEditModeXML()); } } public void focusLost(FocusEvent e) { if (schemaFrame.getContentPane() .getComponent(0) instanceof SchemaExplorer) { SchemaExplorer se = (SchemaExplorer) schemaFrame.getContentPane().getComponent(0); // update view menu based on viewXmlMenuItem.setSelected( se.isEditModeXML()); } } }); viewXmlMenuItem.setSelected(false); } catch (Exception ex) { LOGGER.error("openSchemaFrame", ex); } finally { setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); } } private void openMenuItemActionPerformed(ActionEvent evt) { JFileChooser jfc = new JFileChooser(); try { jfc.setFileSelectionMode(JFileChooser.FILES_ONLY); jfc.setFileFilter( new javax.swing.filechooser.FileFilter() { public boolean accept(File pathname) { return pathname.getName().toLowerCase().endsWith(".xml") || pathname.isDirectory(); } public String getDescription() { return getResourceConverter().getString( "workbench.open.schema.file.type", "Mondrian Schema files (*.xml)"); } }); String lastUsed = getWorkbenchProperty(LAST_USED1_URL); if (lastUsed != null) { jfc.setCurrentDirectory(new File(new URI(lastUsed))); } } catch (Exception ex) { LOGGER.error("Could not set file chooser", ex); } MondrianProperties.instance(); if (jfc.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) { try { setLastUsed( jfc.getSelectedFile().getName(), jfc.getSelectedFile().toURI().toURL().toString()); } catch (MalformedURLException e) { LOGGER.error(e); } openSchemaFrame(jfc.getSelectedFile(), false); } } // checks if file already open in schema explorer private boolean checkFileOpen(File file) { Iterator<JInternalFrame> it = schemaWindowMap.keySet().iterator(); // keys=schemaframes while (it.hasNext()) { JInternalFrame elem = it.next(); File f = ((SchemaExplorer) elem.getContentPane().getComponent(0)) .getSchemaFile(); if (f.equals(file)) { try { // make the schema file active elem.setSelected(true); return true; } catch (Exception ex) { // remove file from map as schema frame does not exist schemaWindowMap.remove(elem); break; } } } return false; } private void getNewJdbcMetadata() { jdbcMetaData = new JdbcMetaData( this, jdbcDriverClassName, jdbcConnectionUrl, jdbcUsername, jdbcPassword, jdbcSchema, requireSchema); } /** * Updates the JdbcMetaData for each SchemaExplorer contained in each Schema * Frame currently opened based on the JDBC preferences entered. */ private void resetWorkbench() { getNewJdbcMetadata(); Iterator<JInternalFrame> theSchemaFrames = schemaWindowMap.keySet().iterator(); while (theSchemaFrames.hasNext()) { JInternalFrame theSchemaFrame = theSchemaFrames.next(); SchemaExplorer theSchemaExplorer = (SchemaExplorer) theSchemaFrame.getContentPane() .getComponent(0); File theFile = theSchemaExplorer.getSchemaFile(); checkSchemaFile(theFile); theSchemaExplorer.resetMetaData(jdbcMetaData); theSchemaExplorer.getTreeUpdater().update(); theSchemaFrame.updateUI(); } // EC: If the JDBC preferences entered then display a warning. displayWarningOnFailedConnection(); for (JInternalFrame jdbcFrame : jdbcWindows) { JdbcExplorer explorer = (JdbcExplorer) jdbcFrame.getContentPane().getComponent(0); explorer.resetMetaData(jdbcMetaData); jdbcFrame.setTitle( getResourceConverter().getFormattedString( "workbench.new.JDBCExplorer.title", "JDBC Explorer - {0} {1}", jdbcMetaData.getDatabaseProductName(), jdbcMetaData.getJdbcConnectionUrl())); explorer.getTreeUpdater().update(); explorer.updateUI(); } } /** * Display jdbc connection status warning, if connection is uncsuccessful. */ private void displayWarningOnFailedConnection() { if (jdbcMetaData != null && jdbcMetaData.getErrMsg() != null) { JOptionPane.showMessageDialog( this, getResourceConverter().getFormattedString( "workbench.open.schema.jdbc.error", "Database connection could not be done.\n{0}\nAll validations related to database will be ignored.", jdbcMetaData.getErrMsg()), getResourceConverter().getString( "workbench.open.schema.jdbc.error.title", "Alert"), JOptionPane.WARNING_MESSAGE); } } /** * Check if schema file is valid by initiating a mondrian connection. */ private void checkSchemaFile(File file) { try { // this connection parses the catalog file which if invalid will // throw exception PropertyList list = new PropertyList(); list.put("Provider", "mondrian"); list.put("Jdbc", jdbcConnectionUrl); list.put("Catalog", file.toURI().toURL().toString()); list.put("JdbcDrivers", jdbcDriverClassName); if (jdbcUsername != null && jdbcUsername.length() > 0) { list.put("JdbcUser", jdbcUsername); } if (jdbcPassword != null && jdbcPassword.length() > 0) { list.put("JdbcPassword", jdbcPassword); } DriverManager.getConnection(list, null); } catch (Exception ex) { LOGGER.error( "Exception : Schema file " + file.getAbsolutePath() + " is invalid." + ex.getMessage(), ex); } catch (Error err) { LOGGER.error( "Error : Schema file " + file.getAbsolutePath() + " is invalid." + err.getMessage(), err); } } private void exitMenuItemActionPerformed(ActionEvent evt) { storeWorkbenchProperties(); storeDatabaseMeta(); closeAllSchemaFrames(true); } /** * Parses arguments passed into Workbench. * * <p>Right now, it's very simple. Just search through the list of * arguments. If it begins with -f=, then the rest is a file name. Ignore * any others. We can make this more complicated later if we need to. * * @param args the command line arguments */ private void parseArgs(String args[]) { for (int argNum = 0; argNum < args.length; argNum++) { if (args[argNum].startsWith("-f=")) { openFile = args[argNum].substring(3); } } } public String getTooltip(String titleName) { try { return getWorkbenchResourceBundle().getString(titleName); } catch (MissingResourceException e) { return getResourceConverter().getFormattedString( "workbench.tooltip.error", "No help available for {0}", titleName); } } /** * @param args the command line arguments */ public static void main(String args[]) { Workbench w = null; try { w = new Workbench(); w.parseArgs(args); w.setSize(800, 600); // if user specified a file to open, do so now. if (w.openFile != null) { File f = new File(w.openFile); if (f.canRead()) { w.openSchemaFrame( f.getAbsoluteFile(), // parameter to indicate this is a new or existing // catalog file false); } } w.setVisible(true); } catch (Throwable ex) { if (w != null) { JOptionPane.showMessageDialog( w, w.getResourceConverter().getFormattedString( "workbench.main.uncoverable_error", "Pentaho Schema Workbench has encountered an unrecoverable error. \n{0}", ex.getLocalizedMessage()), w.getResourceConverter().getString( "workbench.main.uncoverable_error.title", "PSW Fatal Error"), JOptionPane.ERROR_MESSAGE); } LOGGER.error("main", ex); } } // Variables declaration - do not modify private javax.swing.JButton toolbarSaveAsButton; private javax.swing.JMenuItem openMenuItem; private javax.swing.JMenuItem lastUsed1MenuItem; private javax.swing.JMenuItem lastUsed2MenuItem; private javax.swing.JMenuItem lastUsed3MenuItem; private javax.swing.JMenuItem lastUsed4MenuItem; private javax.swing.JMenu fileMenu; private javax.swing.JMenuItem newQueryMenuItem; private javax.swing.JMenuItem newQueryMenuItem2; private javax.swing.JPanel jPanel1; private javax.swing.JPanel jPanel2; private javax.swing.JButton toolbarOpenButton; private javax.swing.JButton toolbarNewButton; private javax.swing.JButton toolbarNewArrowButton; private javax.swing.JSeparator jSeparator1; private javax.swing.JSeparator jSeparator2; private javax.swing.JSeparator jSeparator3; private javax.swing.JMenuItem cutMenuItem; private javax.swing.JMenuBar menuBar; private javax.swing.JMenuItem saveMenuItem; private javax.swing.JMenuItem newJDBCExplorerMenuItem; private javax.swing.JMenuItem newJDBCExplorerMenuItem2; private javax.swing.JButton toolbarSaveButton; private javax.swing.JMenuItem copyMenuItem; private javax.swing.JDesktopPane desktopPane; private javax.swing.JMenu viewMenu; private javax.swing.JMenu toolsMenu; private javax.swing.JMenu newMenu; private javax.swing.JMenuItem deleteMenuItem; private javax.swing.JMenuItem newSchemaMenuItem; private javax.swing.JMenuItem newSchemaMenuItem2; private javax.swing.JMenuItem exitMenuItem; private javax.swing.JButton toolbarPreferencesButton; private javax.swing.JCheckBoxMenuItem requireSchemaCheckboxMenuItem; private javax.swing.JMenu editMenu; private javax.swing.JMenuItem pasteMenuItem; private javax.swing.JMenuItem preferencesMenuItem; private javax.swing.JCheckBoxMenuItem viewXmlMenuItem; private javax.swing.JMenuItem saveAsMenuItem; private javax.swing.JToolBar jToolBar1; private javax.swing.JToolBar jToolBar2; private javax.swing.JPopupMenu toolbarNewPopupMenu; private javax.swing.JMenu windowMenu; private javax.swing.JMenu helpMenu; private javax.swing.JMenuItem aboutMenuItem; private javax.swing.JMenuItem cascadeMenuItem; private javax.swing.JMenuItem tileMenuItem; private javax.swing.JMenuItem minimizeMenuItem; private javax.swing.JMenuItem maximizeMenuItem; private javax.swing.JMenuItem closeAllMenuItem; // End of variables declaration /** * Used by schema framewhen it uses 'view xml' to update view xml menu item */ public javax.swing.JCheckBoxMenuItem getViewXmlMenuItem() { return viewXmlMenuItem; } } // End Workbench.java