/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package ro.nextreports.designer.querybuilder; import java.awt.Color; import java.awt.Component; import java.awt.Point; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; import java.awt.dnd.DnDConstants; import java.awt.dnd.DragGestureEvent; import java.awt.dnd.DragGestureListener; import java.awt.dnd.DragGestureRecognizer; import java.awt.dnd.DragSource; import java.awt.dnd.DragSourceAdapter; import java.awt.dnd.DragSourceDragEvent; import java.awt.dnd.DragSourceEvent; import java.awt.dnd.DropTarget; import java.awt.dnd.DropTargetDragEvent; import java.awt.dnd.DropTargetDropEvent; import java.awt.dnd.DropTargetEvent; import java.awt.dnd.DropTargetListener; import java.awt.event.ActionEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.text.Collator; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPopupMenu; import javax.swing.JTree; import javax.swing.SwingUtilities; import javax.swing.event.TreeExpansionEvent; import javax.swing.event.TreeExpansionListener; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; import javax.swing.tree.TreeSelectionModel; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jdesktop.swingx.JXTree; import org.jdesktop.swingx.decorator.ColorHighlighter; import org.jdesktop.swingx.decorator.HighlightPredicate; import ro.nextreports.designer.FormLoader; import ro.nextreports.designer.FormSaver; import ro.nextreports.designer.Globals; import ro.nextreports.designer.action.DownloadBulkChartAction; import ro.nextreports.designer.action.DownloadBulkReportAction; import ro.nextreports.designer.action.NamePatternAction; import ro.nextreports.designer.action.PublishBulkChartAction; import ro.nextreports.designer.action.PublishBulkReportAction; import ro.nextreports.designer.action.chart.DeleteChartAction; import ro.nextreports.designer.action.chart.ExportChartAction; import ro.nextreports.designer.action.chart.ImportChartAction; import ro.nextreports.designer.action.chart.NewChartFromQueryAction; import ro.nextreports.designer.action.chart.OpenChartAction; import ro.nextreports.designer.action.chart.PreviewChartAction; import ro.nextreports.designer.action.chart.PublishChartAction; import ro.nextreports.designer.action.chart.RenameChartAction; import ro.nextreports.designer.action.datasource.AddDataSourceAction; import ro.nextreports.designer.action.datasource.DataSourceConnectAction; import ro.nextreports.designer.action.datasource.DataSourceDeleteAction; import ro.nextreports.designer.action.datasource.DataSourceDisconnectAction; import ro.nextreports.designer.action.datasource.DataSourceEditAction; import ro.nextreports.designer.action.datasource.DataSourceSchemaSelectionAction; import ro.nextreports.designer.action.datasource.DataSourceViewInfoAction; import ro.nextreports.designer.action.favorites.AddToFavoritesAction; import ro.nextreports.designer.action.folder.AddFolderAction; import ro.nextreports.designer.action.folder.DeleteFolderAction; import ro.nextreports.designer.action.folder.RenameFolderAction; import ro.nextreports.designer.action.query.DeleteQueryAction; import ro.nextreports.designer.action.query.ExportQueryAction; import ro.nextreports.designer.action.query.ImportQueryAction; import ro.nextreports.designer.action.query.NewQueryAction; import ro.nextreports.designer.action.query.OpenQueryAction; import ro.nextreports.designer.action.query.RenameQueryAction; import ro.nextreports.designer.action.query.ValidateProceduresAction; import ro.nextreports.designer.action.query.ValidateSqlsAction; import ro.nextreports.designer.action.query.ViewProcedureColumnsInfoAction; import ro.nextreports.designer.action.query.ViewTableColumnsInfoAction; import ro.nextreports.designer.action.report.DeleteReportAction; import ro.nextreports.designer.action.report.ExportReportAction; import ro.nextreports.designer.action.report.ImportReportAction; import ro.nextreports.designer.action.report.NewReportFromQueryAction; import ro.nextreports.designer.action.report.OpenReportAction; import ro.nextreports.designer.action.report.PublishReportAction; import ro.nextreports.designer.action.report.RenameReportAction; import ro.nextreports.designer.action.report.layout.export.ExportToCsvAction; import ro.nextreports.designer.action.report.layout.export.ExportToDocxAction; import ro.nextreports.designer.action.report.layout.export.ExportToExcelAction; import ro.nextreports.designer.action.report.layout.export.ExportToExcelXAction; import ro.nextreports.designer.action.report.layout.export.ExportToHtmlAction; import ro.nextreports.designer.action.report.layout.export.ExportToJSONFullAction; import ro.nextreports.designer.action.report.layout.export.ExportToJSONSimpleAction; import ro.nextreports.designer.action.report.layout.export.ExportToPdfAction; import ro.nextreports.designer.action.report.layout.export.ExportToRtfAction; import ro.nextreports.designer.action.report.layout.export.ExportToTsvAction; import ro.nextreports.designer.action.report.layout.export.ExportToTxtAction; import ro.nextreports.designer.action.report.layout.export.ExportToXmlAction; import ro.nextreports.designer.chart.ChartUtil; import ro.nextreports.designer.datasource.DataSource; import ro.nextreports.designer.datasource.DataSourceManager; import ro.nextreports.designer.datasource.DataSourceType; import ro.nextreports.designer.datasource.DefaultDataSourceManager; import ro.nextreports.designer.datasource.exception.NotFoundException; import ro.nextreports.designer.dbviewer.common.DBProcedure; import ro.nextreports.designer.persistence.FileReportPersistence; import ro.nextreports.designer.persistence.ReportPersistence; import ro.nextreports.designer.persistence.ReportPersistenceFactory; import ro.nextreports.designer.querybuilder.datatransfer.DBProcTransferable; import ro.nextreports.designer.querybuilder.datatransfer.DBTableTransferable; import ro.nextreports.designer.querybuilder.datatransfer.FileTransferable; import ro.nextreports.designer.querybuilder.tree.DBNodeExpander; import ro.nextreports.designer.querybuilder.tree.NodeExpander; import ro.nextreports.designer.util.FileUtil; import ro.nextreports.designer.util.I18NSupport; import ro.nextreports.designer.util.ImageUtil; import ro.nextreports.designer.util.Show; import ro.nextreports.engine.Report; import ro.nextreports.engine.chart.Chart; import ro.nextreports.engine.chart.ChartRunner; import ro.nextreports.engine.chart.ChartType; import ro.nextreports.engine.querybuilder.sql.Table; import ro.nextreports.engine.util.DialectUtil; import ro.nextreports.engine.util.ReportUtil; /** * @author Decebal Suiu */ public class DBBrowserTree extends JXTree { private static final Log LOG = LogFactory.getLog(DBBrowserTree.class); private DBBrowserTreeModel model; private DBBrowserTree instance; private byte typeRoot; public DBBrowserTree() { this(DBObject.DATASOURCE, true); } public DBBrowserTree(byte typeRoot) { this(typeRoot, true); } /** * Constructor * * @param typeRoot * is used to create the tree starting from a specific type node * @param registerDoubleClick * register mouse double click on tree */ public DBBrowserTree(byte typeRoot, boolean registerDoubleClick) { super(); this.typeRoot = typeRoot; populateTree(typeRoot); setCellRenderer(new DBBrowserTreeRenderer()); getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); setRolloverEnabled(true); addHighlighter(new ColorHighlighter(HighlightPredicate.ROLLOVER_ROW, null, Color.RED)); DragGestureRecognizer dgr = DragSource.getDefaultDragSource().createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_COPY_OR_MOVE, new DBBrowserTreeDragGestureListener()); DBBrowserTreeDropListener dropListener = new DBBrowserTreeDropListener(); addTreeSelectionListener(dropListener); setDropTarget(new DropTarget(this, dropListener)); if (registerDoubleClick) { addMouseDoubleClickListener(); } instance = this; // single data source autoconnect DataSourceManager manager = DefaultDataSourceManager.getInstance(); List<DataSource> sources = manager.getDataSources(); if (sources.size() == 1) { if (Globals.singleSourceAutoConnect()) { DataSource ds = manager.getConnectedDataSource(); if (ds == null) { connectToDataSource(sources.get(0).getName()); } } } else { String dataSourceName = Globals.getSystemDataSource(); DataSource ds = manager.getDataSource(dataSourceName); if (ds != null) { connectToDataSource(dataSourceName); } } } private void connectToDataSource(String dataSourceName) { try { if (DefaultDataSourceManager.getInstance().getConnectedDataSource() != null) { return; // already connected } DefaultDataSourceManager.getInstance().connect(dataSourceName); DBBrowserNode node = searchNode(DBNodeExpander.CONNECTIONS); if (node.getChildCount() == 0) { return; } DBBrowserNode selectedNode = searchNode(dataSourceName, DBObject.DATABASE); // select data source node and expand it TreeNode[] nodes = model.getPathToRoot(selectedNode); TreePath path = new TreePath(nodes); scrollPathToVisible(path); setSelectionPath(path); instance.fireTreeExpanded(path); } catch (Exception e) { LOG.error(e.getMessage(), e); e.printStackTrace(); } } private void addMouseDoubleClickListener() { addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent e) { job(e, true); } public void mouseReleased(MouseEvent e) { job(e, false); } private void job(MouseEvent e, boolean pressed) { if (e.isPopupTrigger() || (e.getClickCount() == 2)) { final TreePath selPath = getPathForLocation(e.getX(), e.getY()); if (selPath == null) { return; } setSelectionPath(selPath); try { final DBBrowserNode selectedNode = (DBBrowserNode) selPath.getLastPathComponent(); if (selectedNode != null) { if (selectedNode.getDBObject().getType() == DBObject.DATASOURCE) { selectionDataSource(e); } else if (selectedNode.getDBObject().getType() == DBObject.QUERIES_GROUP) { selectionQueryGroup(selectedNode, e); } else if (selectedNode.getDBObject().getType() == DBObject.QUERIES) { selectionQuery(selectedNode, e, pressed); } else if (selectedNode.getDBObject().getType() == DBObject.REPORTS_GROUP) { selectionReportGroup(selectedNode, e); } else if (selectedNode.getDBObject().getType() == DBObject.REPORTS) { selectionReport(selectedNode, e, pressed); } else if (selectedNode.getDBObject().getType() == DBObject.CHARTS_GROUP) { selectionChartGroup(selectedNode, e); } else if (selectedNode.getDBObject().getType() == DBObject.CHARTS) { selectionChart(selectedNode, e, pressed); } else if (selectedNode.getDBObject().getType() == DBObject.DATABASE) { selectionDatabase(selPath, selectedNode, e); } else if ((selectedNode.getDBObject().getType() == DBObject.TABLE) || (selectedNode.getDBObject().getType() == DBObject.VIEW)) { selectionTableOrView(selectedNode, e); } else if (selectedNode.getDBObject().getType() == DBObject.PROCEDURES) { selectionProcedure(selectedNode, e); } else if (selectedNode.getDBObject().getType() == DBObject.PROCEDURES_GROUP) { selectionProcedureGroup(selectedNode, e); } else if (selectedNode.getDBObject().getType() == DBObject.TABLES_GROUP) { selectionTablesGroup(selectedNode, e); } else if (selectedNode.getDBObject().getType() == DBObject.VIEWS_GROUP) { selectionViewsGroup(selectedNode, e); } else if (selectedNode.getDBObject().isFolder()) { selectionFolder(selectedNode, e); } } } catch (Exception ex) { Show.error(ex); } } } }); } private void selectionDataSource(MouseEvent e) { if (e.getClickCount() == 2) { return; } AddDataSourceAction addDSAction = new AddDataSourceAction(); JPopupMenu popupMenu = new JPopupMenu(); JMenuItem menuItem = new JMenuItem(addDSAction); popupMenu.add(menuItem); popupMenu.show((Component) e.getSource(), e.getX(), e.getY()); } private void selectionQueryGroup(DBBrowserNode selectedNode, MouseEvent e) { if (e.getClickCount() == 2) { return; } ImportQueryAction importAction = new ImportQueryAction(); JPopupMenu popupMenu = new JPopupMenu(); JMenuItem menuItem = new JMenuItem(importAction); popupMenu.add(menuItem); JMenuItem menuItem2 = new JMenuItem(new AddFolderAction(this, selectedNode, DBObject.FOLDER_QUERY)); popupMenu.add(menuItem2); JMenuItem menuItem3 = new JMenuItem(new ValidateSqlsAction(selectedNode.getDBObject())); popupMenu.add(menuItem3); popupMenu.show((Component) e.getSource(), e.getX(), e.getY()); } private void selectionQuery(DBBrowserNode selectedNode, MouseEvent e, boolean pressed) { OpenQueryAction openAction = new OpenQueryAction(); openAction.setQueryName(selectedNode.getDBObject().getName()); openAction.setQueryPath(selectedNode.getDBObject().getAbsolutePath()); if (e.getClickCount() == 2) { if (pressed) { openAction.actionPerformed(new ActionEvent(e.getSource(), e.getID(), "")); } } else { JPopupMenu popupMenu = new JPopupMenu(); JMenuItem menuItem = new JMenuItem(openAction); popupMenu.add(menuItem); NewReportFromQueryAction newReportQAction = new NewReportFromQueryAction(); newReportQAction.setQueryName(selectedNode.getDBObject().getName()); newReportQAction.setQueryPath(selectedNode.getDBObject().getAbsolutePath()); JMenuItem menuItem3 = new JMenuItem(newReportQAction); popupMenu.add(menuItem3); NewChartFromQueryAction newChartQAction = new NewChartFromQueryAction(); newChartQAction.setQueryName(selectedNode.getDBObject().getName()); newChartQAction.setQueryPath(selectedNode.getDBObject().getAbsolutePath()); JMenuItem menuItem6 = new JMenuItem(newChartQAction); popupMenu.add(menuItem6); DeleteQueryAction deleteAction = new DeleteQueryAction(instance, selectedNode); JMenuItem menuItem2 = new JMenuItem(deleteAction);// popupMenu.add(menuItem2); RenameQueryAction renameAction = new RenameQueryAction(instance, selectedNode); JMenuItem menuItem4 = new JMenuItem(renameAction); popupMenu.add(menuItem4); ExportQueryAction exportAction = new ExportQueryAction(instance, selectedNode); JMenuItem menuItem5 = new JMenuItem(exportAction); popupMenu.add(menuItem5); JMenuItem menuItem7 = new JMenuItem(new ValidateSqlsAction(selectedNode.getDBObject())); popupMenu.add(menuItem7); popupMenu.show((Component) e.getSource(), e.getX(), e.getY()); } } private void selectionReportGroup(DBBrowserNode selectedNode, MouseEvent e) { if (e.getClickCount() == 2) { return; } ImportReportAction importAction = new ImportReportAction(); JPopupMenu popupMenu = new JPopupMenu(); JMenuItem menuItem = new JMenuItem(importAction); popupMenu.add(menuItem); JMenuItem menuItem2 = new JMenuItem(new AddFolderAction(this, selectedNode, DBObject.FOLDER_REPORT)); popupMenu.add(menuItem2); JMenuItem menuItem3 = new JMenuItem(new ValidateSqlsAction(selectedNode.getDBObject())); popupMenu.add(menuItem3); JMenuItem menuItem4 = new JMenuItem(new PublishBulkReportAction()); popupMenu.add(menuItem4); JMenuItem menuItem5 = new JMenuItem( new DownloadBulkReportAction(FileReportPersistence.getReportsAbsolutePath())); popupMenu.add(menuItem5); popupMenu.show((Component) e.getSource(), e.getX(), e.getY()); } private void selectionReport(DBBrowserNode selectedNode, MouseEvent e, boolean pressed) { OpenReportAction openAction = new OpenReportAction(); openAction.setReportName(selectedNode.getDBObject().getName()); openAction.setReportPath(selectedNode.getDBObject().getAbsolutePath()); if (e.getClickCount() == 2) { if (pressed) { openAction.actionPerformed(new ActionEvent(e.getSource(), e.getID(), "")); } } else { JPopupMenu popupMenu = new JPopupMenu(); JMenuItem menuItem = new JMenuItem(openAction); popupMenu.add(menuItem); DeleteReportAction deleteAction = new DeleteReportAction(instance, selectedNode); JMenuItem menuItem2 = new JMenuItem(deleteAction); popupMenu.add(menuItem2); RenameReportAction renameAction = new RenameReportAction(instance, selectedNode); JMenuItem menuItem3 = new JMenuItem(renameAction); popupMenu.add(menuItem3); ExportReportAction exportAction = new ExportReportAction(instance, selectedNode); JMenuItem menuItem4 = new JMenuItem(exportAction); popupMenu.add(menuItem4); Report report = FormLoader.getInstance().load(selectedNode.getDBObject().getAbsolutePath(), false); JMenu runMenu = new JMenu(I18NSupport.getString("export")); Globals.setTreeReportAbsolutePath(selectedNode.getDBObject().getAbsolutePath()); runMenu.add(new JMenuItem(new ExportToHtmlAction(report))); runMenu.add(new JMenuItem(new ExportToExcelAction(report))); runMenu.add(new JMenuItem(new ExportToExcelXAction(report))); runMenu.add(new JMenuItem(new ExportToPdfAction(report))); runMenu.add(new JMenuItem(new ExportToDocxAction(report))); runMenu.add(new JMenuItem(new ExportToRtfAction(report))); runMenu.add(new JMenuItem(new ExportToCsvAction(report))); runMenu.add(new JMenuItem(new ExportToTsvAction(report))); runMenu.add(new JMenuItem(new ExportToXmlAction(report))); runMenu.add(new JMenuItem(new ExportToTxtAction(report))); runMenu.add(new JMenuItem(new ExportToJSONSimpleAction(report))); runMenu.add(new JMenuItem(new ExportToJSONFullAction(report))); popupMenu.add(runMenu); PublishReportAction publishAction = new PublishReportAction(selectedNode.getDBObject().getAbsolutePath()); JMenuItem menuItem5 = new JMenuItem(publishAction); popupMenu.add(menuItem5); JMenuItem menuItem6 = new JMenuItem(new ValidateSqlsAction(selectedNode.getDBObject())); popupMenu.add(menuItem6); JMenuItem menuItem7 = new JMenuItem(new AddToFavoritesAction(selectedNode.getDBObject())); popupMenu.add(menuItem7); popupMenu.show((Component) e.getSource(), e.getX(), e.getY()); } } private void selectionChartGroup(DBBrowserNode selectedNode, MouseEvent e) { if (e.getClickCount() == 2) { return; } JPopupMenu popupMenu = new JPopupMenu(); ImportChartAction importAction = new ImportChartAction(); JMenuItem menuItem = new JMenuItem(importAction); popupMenu.add(menuItem); JMenuItem menuItem2 = new JMenuItem(new AddFolderAction(this, selectedNode, DBObject.FOLDER_CHART)); popupMenu.add(menuItem2); JMenuItem menuItem3 = new JMenuItem(new ValidateSqlsAction(selectedNode.getDBObject())); popupMenu.add(menuItem3); JMenuItem menuItem4 = new JMenuItem(new PublishBulkChartAction()); popupMenu.add(menuItem4); JMenuItem menuItem5 = new JMenuItem(new DownloadBulkChartAction(FileReportPersistence.getChartsAbsolutePath())); popupMenu.add(menuItem5); popupMenu.show((Component) e.getSource(), e.getX(), e.getY()); } private void selectionChart(DBBrowserNode selectedNode, MouseEvent e, boolean pressed) { OpenChartAction openAction = new OpenChartAction(); openAction.setChartName(selectedNode.getDBObject().getName()); openAction.setChartPath(selectedNode.getDBObject().getAbsolutePath()); if (e.getClickCount() == 2) { if (pressed) { openAction.actionPerformed(new ActionEvent(e.getSource(), e.getID(), "")); } } else { JPopupMenu popupMenu = new JPopupMenu(); JMenuItem menuItem = new JMenuItem(openAction); popupMenu.add(menuItem); DeleteChartAction deleteAction = new DeleteChartAction(instance, selectedNode); JMenuItem menuItem2 = new JMenuItem(deleteAction); popupMenu.add(menuItem2); RenameChartAction renameAction = new RenameChartAction(instance, selectedNode); JMenuItem menuItem3 = new JMenuItem(renameAction); popupMenu.add(menuItem3); ExportChartAction exportAction = new ExportChartAction(instance, selectedNode); JMenuItem menuItem4 = new JMenuItem(exportAction); popupMenu.add(menuItem4); Chart chart = ChartUtil.loadChart(selectedNode.getDBObject().getAbsolutePath()); PreviewChartAction previewHTML5Action = new PreviewChartAction(ChartRunner.GRAPHIC_FORMAT, ChartRunner.HTML5_TYPE, I18NSupport.getString("preview.html5")); previewHTML5Action.setChart(chart); popupMenu.add(previewHTML5Action); PreviewChartAction previewFlashAction = new PreviewChartAction(ChartRunner.GRAPHIC_FORMAT, ChartRunner.FLASH_TYPE, I18NSupport.getString("preview.flash")); previewFlashAction.setChart(chart); popupMenu.add(previewFlashAction); previewFlashAction.setEnabled(!ChartType.hasNoFlashSupport(chart.getType().getType())); PreviewChartAction previewImageAction = new PreviewChartAction(ChartRunner.IMAGE_FORMAT, ChartRunner.NO_TYPE, I18NSupport.getString("preview.image")); previewImageAction.setChart(chart); popupMenu.add(previewImageAction); PublishChartAction publishAction = new PublishChartAction(selectedNode.getDBObject().getAbsolutePath()); JMenuItem menuItem5 = new JMenuItem(publishAction); popupMenu.add(menuItem5); JMenuItem menuItem6 = new JMenuItem(new ValidateSqlsAction(selectedNode.getDBObject())); popupMenu.add(menuItem6); JMenuItem menuItem7 = new JMenuItem(new AddToFavoritesAction(selectedNode.getDBObject())); popupMenu.add(menuItem7); popupMenu.show((Component) e.getSource(), e.getX(), e.getY()); } } private void selectionDatabase(TreePath selPath, DBBrowserNode selectedNode, MouseEvent e) { if (e.getClickCount() == 2) { return; } boolean connected = false; String name = selectedNode.getDBObject().getName(); DataSourceManager manager = DefaultDataSourceManager.getInstance(); DataSource ds = manager.getDataSource(name); if (ds.getStatus() == DataSourceType.CONNECTED) { connected = true; } else { connected = false; } // try to create source directory (may not exists if we copy // datasource.xml) (new File(FileReportPersistence.CONNECTIONS_DIR + File.separator + name + File.separator + FileReportPersistence.QUERIES_FOLDER)).mkdirs(); (new File(FileReportPersistence.CONNECTIONS_DIR + File.separator + name + File.separator + FileReportPersistence.REPORTS_FOLDER)).mkdirs(); (new File(FileReportPersistence.CONNECTIONS_DIR + File.separator + name + File.separator + FileReportPersistence.CHARTS_FOLDER)).mkdirs(); JPopupMenu popupMenu = new JPopupMenu(); JMenuItem menuItem = new JMenuItem(new DataSourceConnectAction(instance, selPath)); popupMenu.add(menuItem); if (connected) { menuItem.setEnabled(false); } else { menuItem.setEnabled(true); } JMenuItem menuItem2 = new JMenuItem(new DataSourceDisconnectAction(instance, selectedNode)); popupMenu.add(menuItem2); if (connected) { menuItem2.setEnabled(true); } else { menuItem2.setEnabled(false); } JMenuItem menuItem5 = new JMenuItem(new DataSourceViewInfoAction(selectedNode)); popupMenu.add(menuItem5); JMenuItem menuItem3 = new JMenuItem(new DataSourceEditAction(instance, selectedNode)); popupMenu.add(menuItem3); if (connected) { menuItem3.setEnabled(false); } else { menuItem3.setEnabled(true); } JMenuItem menuItem4 = new JMenuItem(new DataSourceDeleteAction(instance, selectedNode)); popupMenu.add(menuItem4); if (connected) { menuItem4.setEnabled(false); } else { menuItem4.setEnabled(true); } if (!DefaultDataSourceManager.memoryDataSources()) { JMenuItem menuItem6 = new JMenuItem(new DataSourceSchemaSelectionAction(instance, selectedNode)); popupMenu.add(menuItem6); } popupMenu.show((Component) e.getSource(), e.getX(), e.getY()); } private void selectionTableOrView(DBBrowserNode selectedNode, MouseEvent e) { boolean isTable = true; if (selectedNode.getDBObject().getType() == DBObject.VIEW) { isTable = false; } ViewTableColumnsInfoAction infoAction = new ViewTableColumnsInfoAction(selectedNode.getDBObject(), isTable); if (e.getClickCount() == 2) { infoAction.actionPerformed(null); } else { JPopupMenu popupMenu = new JPopupMenu(); JMenuItem menuItem = new JMenuItem(infoAction); popupMenu.add(menuItem); popupMenu.show((Component) e.getSource(), e.getX(), e.getY()); } } private void selectionProcedure(DBBrowserNode selectedNode, MouseEvent e) { ViewProcedureColumnsInfoAction infoAction = new ViewProcedureColumnsInfoAction(selectedNode.getDBObject()); if (e.getClickCount() == 2) { infoAction.actionPerformed(null); } else { JPopupMenu popupMenu = new JPopupMenu(); JMenuItem menuItem = new JMenuItem(infoAction); popupMenu.add(menuItem); JMenuItem menuItem2 = new JMenuItem(new ValidateProceduresAction(selectedNode.getDBObject())); popupMenu.add(menuItem2); popupMenu.show((Component) e.getSource(), e.getX(), e.getY()); } } private void selectionProcedureGroup(DBBrowserNode selectedNode, MouseEvent e) { if (e.getClickCount() == 2) { return; } ValidateProceduresAction validateAction = new ValidateProceduresAction(); JPopupMenu popupMenu = new JPopupMenu(); JMenuItem menuItem = new JMenuItem(validateAction); popupMenu.add(menuItem); NamePatternAction patternAction = new NamePatternAction(NamePatternAction.PROCEDURE_NAME_PATTERN); JMenuItem menuItem2 = new JMenuItem(patternAction); popupMenu.add(menuItem2); popupMenu.show((Component) e.getSource(), e.getX(), e.getY()); } private void selectionTablesGroup(DBBrowserNode selectedNode, MouseEvent e) { if (e.getClickCount() == 2) { return; } JPopupMenu popupMenu = new JPopupMenu(); NamePatternAction patternAction = new NamePatternAction(NamePatternAction.TABLE_NAME_PATTERN); JMenuItem menuItem = new JMenuItem(patternAction); popupMenu.add(menuItem); popupMenu.show((Component) e.getSource(), e.getX(), e.getY()); } private void selectionViewsGroup(DBBrowserNode selectedNode, MouseEvent e) { if (e.getClickCount() == 2) { return; } JPopupMenu popupMenu = new JPopupMenu(); NamePatternAction patternAction = new NamePatternAction(NamePatternAction.VIEW_NAME_PATTERN); JMenuItem menuItem = new JMenuItem(patternAction); popupMenu.add(menuItem); popupMenu.show((Component) e.getSource(), e.getX(), e.getY()); } private void selectionFolder(DBBrowserNode selectedNode, MouseEvent e) { if (e.getClickCount() == 2) { return; } JPopupMenu popupMenu = new JPopupMenu(); boolean testSql = false; if (selectedNode.getDBObject().getType() == DBObject.FOLDER_QUERY) { testSql = true; JMenuItem menuItem = new JMenuItem(new ImportQueryAction(selectedNode.getDBObject().getAbsolutePath())); popupMenu.add(menuItem); } else if (selectedNode.getDBObject().getType() == DBObject.FOLDER_REPORT) { testSql = true; JMenuItem menuItem = new JMenuItem(new ImportReportAction(selectedNode.getDBObject().getAbsolutePath())); popupMenu.add(menuItem); JMenuItem menuItem2 = new JMenuItem( new DownloadBulkReportAction(selectedNode.getDBObject().getAbsolutePath())); popupMenu.add(menuItem2); } else if (selectedNode.getDBObject().getType() == DBObject.FOLDER_CHART) { testSql = true; JMenuItem menuItem = new JMenuItem(new ImportChartAction(selectedNode.getDBObject().getAbsolutePath())); popupMenu.add(menuItem); JMenuItem menuItem2 = new JMenuItem( new DownloadBulkChartAction(selectedNode.getDBObject().getAbsolutePath())); popupMenu.add(menuItem2); } JMenuItem menuItem = new JMenuItem( new AddFolderAction(this, selectedNode, selectedNode.getDBObject().getType())); popupMenu.add(menuItem); JMenuItem menuItem2 = new JMenuItem(new RenameFolderAction(this, selectedNode)); popupMenu.add(menuItem2); JMenuItem menuItem3 = new JMenuItem(new DeleteFolderAction(this, selectedNode)); popupMenu.add(menuItem3); if (testSql) { JMenuItem menuItem4 = new JMenuItem(new ValidateSqlsAction(selectedNode.getDBObject())); popupMenu.add(menuItem4); } popupMenu.show((Component) e.getSource(), e.getX(), e.getY()); } private void populateTree(byte typeRoot) { model = new DBBrowserTreeModel(new DBBrowserNode(new DBObject(getRootName(typeRoot), null, typeRoot))); setModel(model); DBBrowserNode root = (DBBrowserNode) model.getRoot(); // if (typeRoot == DBObject.DATABASE ) { // setRootVisible(false); // } addTreeExpansionListener(new NodeExpansionListener()); setShowsRootHandles(true); expandNode(root, false); // for datasource root node expand the group nodes (tables, views, // queries, reports) // this is necessary when starting the applications and open a query // without expanding the tree if (typeRoot == DBObject.DATASOURCE) { if (root.getChildCount() > 0) { expandNode((DBBrowserNode) root.getChildAt(0), false); } } } private String getRootName(byte typeRoot) { switch (typeRoot) { case DBObject.DATASOURCE: return DBNodeExpander.CONNECTIONS; case DBObject.DATABASE: DataSource ds = DefaultDataSourceManager.getInstance().getConnectedDataSource(); if (ds == null) { return "<Database name>"; } else { return ds.getName(); } case DBObject.TABLES_GROUP: return DBNodeExpander.TABLES; case DBObject.VIEWS_GROUP: return DBNodeExpander.VIEWS; case DBObject.QUERIES_GROUP: return DBNodeExpander.QUERIES; case DBObject.REPORTS_GROUP: return DBNodeExpander.REPORTS; case DBObject.CHARTS_GROUP: return DBNodeExpander.CHARTS; case DBObject.PROCEDURES_GROUP: return DBNodeExpander.PROCEDURES; default: return "ROOT"; } } public String getRootAbsolutePath(byte typeRoot) { switch (typeRoot) { case DBObject.REPORTS_GROUP: return FileReportPersistence.getReportsAbsolutePath(); case DBObject.QUERIES_GROUP: return FileReportPersistence.getQueriesAbsolutePath(); case DBObject.CHARTS_GROUP: return FileReportPersistence.getChartsAbsolutePath(); default: throw new IllegalArgumentException("Invalid typeRoot = " + typeRoot); } } /** * This method takes the node string and traverses the tree till it finds * the node matching the string. If the match is found the node is returned * else null is returned * * @param nodeStr * node string to search for * @return tree node */ public DBBrowserNode searchNode(String nodeStr) { DBBrowserNode node = null; Enumeration enumeration = ((DBBrowserNode) model.getRoot()).breadthFirstEnumeration(); while (enumeration.hasMoreElements()) { node = (DBBrowserNode) enumeration.nextElement(); if (nodeStr.equals(node.getUserObject().toString())) { return node; } } return null; } public DBBrowserNode searchNode(String nodeStr, byte type) { // possibly SCHEMA node was not expanded, give it a chance to load // children try { String schemaName = Globals.getDBViewer().getUserSchema(); if (schemaName != null) { DBBrowserNode node = searchNode(schemaName); if (node != null) { if (node.getChildCount() == 0) { startExpandingTree(node, false, null); } } } } catch (Exception e) { LOG.error(e.getMessage(), e); e.printStackTrace(); } DBBrowserNode node = searchNode(DBNodeExpander.getNodeExpanderName(type)); // possibly node of 'type' was not expanded, give it a chance to load // children if (node != null) { if (node.getChildCount() == 0) { startExpandingTree(node, false, null); } } Enumeration enumeration = ((DBBrowserNode) model.getRoot()).breadthFirstEnumeration(); while (enumeration.hasMoreElements()) { node = (DBBrowserNode) enumeration.nextElement(); if (nodeStr.equals(node.getUserObject().toString()) && (node.getDBObject().getType() == type)) { return node; } } return null; } public DBBrowserNode searchNode(String nodeStr, String path, byte type) { Map<String, Boolean> expanded = new HashMap<String, Boolean>(); // possibly SCHEMA node was not expanded, give it a chance to load // children try { String schemaName = Globals.getDBViewer().getUserSchema(); if (schemaName != null) { DBBrowserNode node = searchNode(schemaName); if (node != null) { if (node.getChildCount() == 0) { startExpandingTree(node, false, null); } } } } catch (Exception e) { LOG.error(e.getMessage(), e); e.printStackTrace(); } DBBrowserNode node = searchNode(DBNodeExpander.getNodeExpanderName(type)); // possibly node of 'type' was not expanded, give it a chance to load // children if (node != null) { if (node.getChildCount() == 0) { startExpandingTree(node, false, null); } } boolean done = false; while (!done) { done = true; Enumeration enumeration = ((DBBrowserNode) model.getRoot()).breadthFirstEnumeration(); while (enumeration.hasMoreElements()) { node = (DBBrowserNode) enumeration.nextElement(); // try to expand folder if (node.getDBObject().isFolder()) { // if (node.getChildCount() == 0) { Boolean expand = expanded.get(node.getDBObject().getAbsolutePath()); if ((expand == null) || !expand.booleanValue()) { done = false; expanded.put(node.getDBObject().getAbsolutePath(), true); startExpandingTree(node, false, null); } } // System.out.println("#### path="+path); if (nodeStr.equals(node.getUserObject().toString()) && (node.getDBObject().getType() == type) && path.equals(node.getDBObject().getAbsolutePath())) { return node; } } } return null; } public void selectNode(String name, byte type) { DBBrowserNode foundNode = searchNode(name, type); if (foundNode != null) { TreePath treePath = new TreePath(foundNode.getPath()); this.setSelectionPath(treePath); this.scrollPathToVisible(treePath); } } public void selectNode(String name, String path, byte type) { DBBrowserNode foundNode = searchNode(name, path, type); // System.out.println("----------------"); // System.out.println("name="+name + " path="+path + " type="+type); // System.out.println("foundNode="+foundNode); if (foundNode != null) { TreePath treePath = new TreePath(foundNode.getPath()); this.setSelectionPath(treePath); this.scrollPathToVisible(treePath); } } public void selectNode(DBObject object) { selectNode(object.getName(), object.getAbsolutePath(), object.getType()); } public void loadQueries() { DBBrowserNode node = searchNode(DBNodeExpander.QUERIES); expandNode(node, false); } /** * This method removes the passed tree node from the tree and selects * appropiate node * * @param selNode * node to be removed */ public void removeNode(DBBrowserNode selNode) { if (selNode != null) { // get the parent of the selected node DBBrowserNode parent = (DBBrowserNode) (selNode.getParent()); // if the parent is not null if (parent != null) { // get the sibling node to be selected after removing the // selected node DBBrowserNode toBeSelNode = getSibling(selNode); // if there are no siblings select the parent node after // removing the node if (toBeSelNode == null) { toBeSelNode = parent; } // make the node visible by scroll to it TreeNode[] nodes = model.getPathToRoot(toBeSelNode); TreePath path = new TreePath(nodes); scrollPathToVisible(path); setSelectionPath(path); // remove the node from the parent model.removeNodeFromParent(selNode); } } } public void renameNode(DBBrowserNode selNode, String name, String newAbsolutePath) { if (selNode != null) { selNode.setName(name); if (newAbsolutePath != null) { // System.out.println("--- set abs path="+newAbsolutePath); selNode.getDBObject().setAbsolutePath(newAbsolutePath); } model.nodeChanged(selNode); } } /** * This method returns the previous sibling node if there is no previous * sibling it returns the next sibling if there are no siblings it returns * null * * @param selNode * selected node * @return previous or next sibling, or parent if no sibling */ private DBBrowserNode getSibling(DBBrowserNode selNode) { // get previous sibling DBBrowserNode sibling = (DBBrowserNode) selNode.getPreviousSibling(); if (sibling == null) { // if previous sibling is null, get the next sibling sibling = (DBBrowserNode) selNode.getNextSibling(); } return sibling; } public void addQuery(String name, String path) throws Exception { addEntity(name, path, DBObject.QUERIES); } public void addReport(String name, String path) throws Exception { addEntity(name, path, DBObject.REPORTS); } public void addChart(String name, String path) throws Exception { addEntity(name, path, DBObject.CHARTS); } private void addEntity(String name, String path, byte type) throws Exception { String nodeString; byte folderType; if (type == DBObject.QUERIES) { nodeString = DBNodeExpander.QUERIES; folderType = DBObject.FOLDER_QUERY; } else if (type == DBObject.REPORTS) { nodeString = DBNodeExpander.REPORTS; folderType = DBObject.FOLDER_REPORT; } else { nodeString = DBNodeExpander.CHARTS; folderType = DBObject.FOLDER_CHART; } DBBrowserNode node = searchNode(nodeString); // possibly node was not expanded, give it a chance to load children if (node.getChildCount() == 0) { startExpandingTree(node, false, null); } String schema = Globals.getDBViewer().getUserSchema(); DBObject obj = new DBObject(name, schema, type); obj.setAbsolutePath(path); DBBrowserNode repNode = new DBBrowserNode(obj); repNode.setAllowsChildren(false); String _path = path.substring(0, path.lastIndexOf(File.separator)); int index = _path.lastIndexOf(File.separator); String parentName = _path.substring(index + 1); DBBrowserNode foundNodeP = searchNode(parentName, _path, folderType); DBBrowserNode foundNode = searchNode(name, path, type); // System.out.println("foundNodeP="+foundNodeP); // System.out.println("foundNode="+foundNode); if (foundNode == null) { if (foundNodeP == null) { // try to expand folder if (node.getChildCount() == 0) { startExpandingTree(node, false, null); } else { insertFile(node, repNode); } model.nodeStructureChanged(node); } else { if (foundNodeP.getChildCount() == 0) { startExpandingTree(foundNodeP, false, null); } else { insertFile(foundNodeP, repNode); } model.nodeStructureChanged(foundNodeP); } } } public void addDataSource(String name) { DBBrowserNode node = searchNode(DBNodeExpander.CONNECTIONS); // possibly node was not expanded, give it a chance to load children if (node.getChildCount() == 0) { startExpandingTree(node, false, null); } DBBrowserNode dsNode = new DBBrowserNode(new DBObject(name, null, DBObject.DATABASE)); dsNode.setAllowsChildren(true); DBBrowserNode foundNode = searchNode(name, DBObject.DATABASE); if (foundNode == null) { TreePath path = instance.getSelectionPath(); Enumeration<TreePath> expandedPath = instance.getExpandedDescendants(path); int size = node.getChildCount(); int insertedIndex = size; for (int i = 0; i < size; i++) { DBBrowserNode child = (DBBrowserNode) node.getChildAt(i); if (Collator.getInstance().compare(name, child.getDBObject().getName()) < 0) { insertedIndex = i; break; } } node.insert(dsNode, insertedIndex); model.nodeStructureChanged(node); // keep expanded path if (expandedPath != null) { while (expandedPath.hasMoreElements()) { instance.expandPath(expandedPath.nextElement()); } } } } public void addFolder(String name, String absPath, byte type, boolean onRoot) { DBObject obj = new DBObject(name, null, type); obj.setAbsolutePath(absPath); DBBrowserNode folderNode = new DBBrowserNode(obj); folderNode.setAllowsChildren(true); // System.out.println("add folder name="+name + " absPath="+absPath + " // type="+type); DBBrowserNode foundNode = searchNode(name, absPath, type); // System.out.println("foundNode="+foundNode); if (foundNode == null) { TreePath path = instance.getSelectionPath(); Enumeration<TreePath> expandedPath = instance.getExpandedDescendants(path); DBBrowserNode node; if (onRoot) { if (type == DBObject.FOLDER_QUERY) { node = searchNode(DBNodeExpander.QUERIES); } else if (type == DBObject.FOLDER_REPORT) { node = searchNode(DBNodeExpander.REPORTS); } else { node = searchNode(DBNodeExpander.CHARTS); } } else { String parentPath = absPath.substring(0, absPath.lastIndexOf(File.separator)); String parentName = parentPath.substring(parentPath.lastIndexOf(File.separator) + 1); node = searchNode(parentName, parentPath, type); } insertFolder(node, folderNode); model.nodeStructureChanged(node); // keep expanded path if (expandedPath != null) { while (expandedPath.hasMoreElements()) { instance.expandPath(expandedPath.nextElement()); } } } } // insert folder node to its position (first are folders , then // queries/reports, ordered by name private void insertFolder(DBBrowserNode parentNode, DBBrowserNode folderNode) { int count = parentNode.getChildCount(); int index = 0; for (int i = 0; i < count; i++) { DBBrowserNode node = (DBBrowserNode) parentNode.getChildAt(i); if (node.getDBObject().isFolder()) { int compare = Collator.getInstance().compare(node.getDBObject().getName(), folderNode.getDBObject().getName()); if (compare < 0) { index++; } else { break; } } else { break; } } parentNode.insert(folderNode, index); } // insert file node to its position private void insertFile(DBBrowserNode parentNode, DBBrowserNode fileNode) { int count = parentNode.getChildCount(); int index = 0; for (int i = 0; i < count; i++) { DBBrowserNode node = (DBBrowserNode) parentNode.getChildAt(i); if (node.getDBObject().isFolder()) { index++; } else { int compare = Collator.getInstance().compare(node.getDBObject().getName(), fileNode.getDBObject().getName()); if (compare < 0) { index++; } else { break; } } } parentNode.insert(fileNode, index); } public void deleteFolder(String name, String absPath, byte type) { DBBrowserNode foundNode = searchNode(name, absPath, type); if (foundNode != null) { DBBrowserNode node = (DBBrowserNode) foundNode.getParent(); foundNode.removeFromParent(); model.nodeStructureChanged(node); } } public void renameFolder(String oldName, String newName, String oldAbsolutePath, String newAbsolutePath, byte type) { // System.out.println("oldName="+oldName + " newName="+newName + // " oldPath="+oldAbsolutePath + " newPath=" + newAbsolutePath); DBBrowserNode foundNode = searchNode(oldName, oldAbsolutePath, type); if (foundNode != null) { foundNode.setName(newName); foundNode.getDBObject().setAbsolutePath(newAbsolutePath); model.nodeChanged(foundNode); // change absolute path for all children Enumeration enumeration = foundNode.breadthFirstEnumeration(); while (enumeration.hasMoreElements()) { DBBrowserNode node = (DBBrowserNode) enumeration.nextElement(); String nodePath = node.getDBObject().getAbsolutePath(); String name = nodePath.substring(nodePath.lastIndexOf(File.separator) + 1); String parentPath = ((DBBrowserNode) node.getParent()).getDBObject().getAbsolutePath(); if (parentPath == null) { if (type == DBObject.FOLDER_QUERY) { parentPath = FileReportPersistence.getQueriesAbsolutePath(); } else if (type == DBObject.FOLDER_REPORT) { parentPath = FileReportPersistence.getReportsAbsolutePath(); } else { parentPath = FileReportPersistence.getChartsAbsolutePath(); } } String path = parentPath + File.separator + name; // System.out.println("oldPath =" + // node.getDBObject().getAbsolutePath() + " new path = " + // path); node.getDBObject().setAbsolutePath(path); } } } public void modifyDataSource(String oldName, String name) { DBBrowserNode node = searchNode(DBNodeExpander.CONNECTIONS); // possibly node was not expanded, give it a chance to load children if (node.getChildCount() == 0) { startExpandingTree(node, false, null); } DBBrowserNode dsNode = new DBBrowserNode(new DBObject(name, null, DBObject.DATABASE)); dsNode.setAllowsChildren(true); DBBrowserNode foundNode = searchNode(oldName); // System.out.println(">> found = " + foundNode); if (foundNode != null) { renameNode(foundNode, name, null); model.nodeStructureChanged(node); } } public void refreshTreeOnRestore() { // clear anything inside query and report panels NewQueryAction nq = new NewQueryAction(); nq.actionPerformed(null); if (!nq.executed()) { return; } // disconnect data source if connected DataSource ds = DefaultDataSourceManager.getInstance().getConnectedDataSource(); if (ds != null) { try { DefaultDataSourceManager.getInstance().disconnect(ds.getName()); } catch (NotFoundException e) { LOG.error(e.getMessage(), e); e.printStackTrace(); } } // load connections from datasource.xml DefaultDataSourceManager.getInstance().load(); populateTree(DBObject.DATASOURCE); model.reload(); } public void refreshSchemas(String dbName) { DBBrowserNode node = searchNode(dbName, DBObject.DATABASE); if (node != null) { node.removeAllChildren(); expandNode(node, false); } } public void refreshParentNode(DBBrowserNode node) { if (node == null) { node = searchNode(getRootName(typeRoot)); } if (node != null) { node.removeAllChildren(); expandNode(node, false); } } public void startExpandingTree(DBBrowserNode node, boolean selectNode, Map selectedPathNames) { expandNode(node, selectNode); } private boolean expandNode(DBBrowserNode node, boolean selectNode) { if (node == null) { throw new IllegalArgumentException("DBBrowserNode is null"); } // if node hasn't already been expanded. if (node.getChildCount() == 0) { // add together the standard expanders for this node type and any // individual expanders that there are for the node and process // them. final byte nodeType = node.getDBObject().getType(); NodeExpander[] expanders = model.getExpanders(nodeType); new TreeLoader(node, expanders, selectNode).execute(); return true; } return false; } class NodeExpansionListener implements TreeExpansionListener { public void treeExpanded(TreeExpansionEvent ev) { final TreePath path = ev.getPath(); final Object parentObj = path.getLastPathComponent(); if (parentObj instanceof DBBrowserNode) { startExpandingTree((DBBrowserNode) parentObj, false, null); // expandedPathNames.put(path.toString(), null); } } public void treeCollapsed(TreeExpansionEvent ev) { // expandedPathNames.remove(ev.getPath().toString()); } } class TreeLoader { private DBBrowserNode parentNode; private NodeExpander[] expanders; private boolean selectParentNode; TreeLoader(DBBrowserNode parentNode, NodeExpander[] expanders, boolean selectParentNode) { super(); this.parentNode = parentNode; this.expanders = expanders; this.selectParentNode = selectParentNode; } void execute() { try { try { loadChildren(); } finally { fireStructureChanged(parentNode); if (selectParentNode) { clearSelection(); setSelectionPath(new TreePath(parentNode.getPath())); } } } catch (Throwable e) { LOG.error(e.getMessage(), e); e.printStackTrace(); } } /** * This expands the parent node and shows all its children. */ private void loadChildren() throws Exception { for (int i = 0; i < expanders.length; ++i) { boolean nodeTypeAllowsChildren = false; byte lastNodeType = -1; List list = expanders[i].createChildren(parentNode); Iterator it = list.iterator(); while (it.hasNext()) { Object nextObj = it.next(); if (nextObj instanceof DBBrowserNode) { DBBrowserNode childNode = (DBBrowserNode) nextObj; byte childNodeType = childNode.getDBObject().getType(); if (childNodeType != lastNodeType) { lastNodeType = childNodeType; if (model.getExpanders(childNodeType).length > 0) { nodeTypeAllowsChildren = true; } else { nodeTypeAllowsChildren = false; } } childNode.setAllowsChildren(nodeTypeAllowsChildren); parentNode.add(childNode); } } } } /** * Let the object tree model know that its structure has changed. */ private void fireStructureChanged(final DBBrowserNode node) { DBBrowserTree.this.model.nodeStructureChanged(node); } } class DBBrowserTreeRenderer extends DefaultTreeCellRenderer { public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus); DBBrowserNode node = (DBBrowserNode) value; setText((String) node.getUserObject()); switch (node.getDBObject().getType()) { // datasource case DBObject.DATASOURCE: setIcon(ImageUtil.getImageIcon("connection")); break; // databse case DBObject.DATABASE: DataSource dataSource = DefaultDataSourceManager.getInstance().getConnectedDataSource(); if (dataSource != null && dataSource.getName().equals(node.getUserObject())) { setIcon(ImageUtil.getImageIcon("database_connect")); } else { setIcon(ImageUtil.getImageIcon("database")); } break; // schema case DBObject.SCHEMA: setIcon(ImageUtil.getImageIcon("schema")); break; // tables group case DBObject.TABLES_GROUP: setIcon(ImageUtil.getImageIcon("entitygroup")); break; // views group case DBObject.VIEWS_GROUP: setIcon(ImageUtil.getImageIcon("entitygroup")); break; case DBObject.PROCEDURES_GROUP: setIcon(ImageUtil.getImageIcon("entitygroup")); break; // tabela case DBObject.TABLE: setIcon(ImageUtil.TABLE_IMAGE_ICON); break; // view case DBObject.VIEW: setIcon(ImageUtil.VIEW_IMAGE_ICON); break; case DBObject.PROCEDURES: Boolean valid = (Boolean) node.getDBObject().getProperty(ValidateProceduresAction.VALID_PROPERTY); if ((valid == null) || (valid.booleanValue() == false)) { setIcon(ImageUtil.PROCEDURE_IMAGE_ICON); } else { setIcon(ImageUtil.PROCEDURE_VALID_IMAGE_ICON); } break; // coloana case DBObject.COLUMN: setIcon(ImageUtil.getImageIcon("column")); break; case DBObject.QUERIES_GROUP: setIcon(ImageUtil.getImageIcon("queries")); break; case DBObject.QUERIES: Boolean validQ = (Boolean) node.getDBObject().getProperty(ValidateSqlsAction.VALID_SQL_PROPERTY); if ((validQ == null) || validQ.booleanValue()) { setIcon(ImageUtil.QUERY_ICON); } else { setIcon(ImageUtil.QUERY_ERROR_ICON); } break; case DBObject.REPORTS_GROUP: setIcon(ImageUtil.getImageIcon("reports")); break; case DBObject.REPORTS: Boolean validR = (Boolean) node.getDBObject().getProperty(ValidateSqlsAction.VALID_SQL_PROPERTY); if ((validR == null) || validR.booleanValue()) { setIcon(ImageUtil.REPORT_ICON); } else { setIcon(ImageUtil.REPORT_ERROR_ICON); } break; case DBObject.CHARTS_GROUP: setIcon(ImageUtil.getImageIcon("charts")); break; case DBObject.CHARTS: Boolean validC = (Boolean) node.getDBObject().getProperty(ValidateSqlsAction.VALID_SQL_PROPERTY); if ((validC == null) || validC.booleanValue()) { setIcon(ImageUtil.CHART_ICON); } else { setIcon(ImageUtil.CHART_ERROR_ICON); } break; case DBObject.FOLDER_QUERY: case DBObject.FOLDER_REPORT: case DBObject.FOLDER_CHART: setIcon(ImageUtil.getImageIcon("folder")); break; } return this; } } class DBBrowserTreeDragGestureListener implements DragGestureListener { public void dragGestureRecognized(DragGestureEvent dge) { TreePath path = DBBrowserTree.this.getSelectionPath(); if (path == null) { return; } DBBrowserNode selectedNode = (DBBrowserNode) path.getLastPathComponent(); byte nodeType = selectedNode.getDBObject().getType(); if ((nodeType == DBObject.TABLE) || (nodeType == DBObject.VIEW)) { Table table = new Table(selectedNode.getDBObject().getName()); table.setSchemaName(selectedNode.getDBObject().getSchemaName()); try { table.setDialect(DialectUtil.getDialect(Globals.getConnection())); } catch (Exception e) { e.printStackTrace(); // To change body of catch statement // use File | Settings | File // Templates. LOG.error(e.getMessage(), e); } Transferable transferable = new DBTableTransferable(table); dge.startDrag(DragSource.DefaultMoveNoDrop, transferable, new DBBrowserTreeDragSourceListener()); } else if (nodeType == DBObject.PROCEDURES) { Transferable transferable = new DBProcTransferable( new DBProcedure(selectedNode.getDBObject().getSchemaName(), selectedNode.getDBObject().getCatalog(), selectedNode.getDBObject().getName(), 0)); dge.startDrag(DragSource.DefaultMoveNoDrop, transferable, new DBBrowserTreeDragSourceListener()); } else if ((nodeType == DBObject.QUERIES) || (nodeType == DBObject.REPORTS) || (nodeType == DBObject.CHARTS) || (nodeType == DBObject.FOLDER_QUERY) || (nodeType == DBObject.FOLDER_REPORT) || (nodeType == DBObject.FOLDER_CHART)) { if ((nodeType == DBObject.REPORTS) || (nodeType == DBObject.CHARTS)) { Globals.setTreeReportAbsolutePath(selectedNode.getDBObject().getAbsolutePath()); } Transferable transferable = new FileTransferable(selectedNode.getDBObject()); dge.startDrag(DragSource.DefaultMoveNoDrop, transferable, new DBBrowserTreeReportDragSourceListener()); } } } class DBBrowserTreeDropListener implements DropTargetListener, TreeSelectionListener { /** * Stores the selected node info */ protected TreePath selectedTreePath = null; protected DBBrowserNode selectedNode = null; public void dragEnter(DropTargetDragEvent dsde) { } public void dragOver(DropTargetDragEvent dtde) { // set cursor location. Needed in setCursor method Point cursorLocationBis = dtde.getLocation(); TreePath destinationPath = getPathForLocation(cursorLocationBis.x, cursorLocationBis.y); Transferable tr = dtde.getTransferable(); // cast into appropriate data type try { DBObject object = (DBObject) tr.getTransferData(FileTransferable.DATA_FLAVOR); if (object == null) { return; } // if destination path is okay accept drop... if (testDropTarget(destinationPath, selectedTreePath, object.getType()) == null) { dtde.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE); } // ...otherwise reject drop else { dtde.rejectDrag(); } } catch (UnsupportedFlavorException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } public void dropActionChanged(DropTargetDragEvent dtde) { } public void dragExit(DropTargetEvent dte) { } /** * DropTargetListener interface method - What we do when drag is * released */ public void drop(DropTargetDropEvent e) { try { Transferable tr = e.getTransferable(); // flavor not supported, reject drop if (!tr.isDataFlavorSupported(FileTransferable.DATA_FLAVOR)) { e.rejectDrop(); } // cast into appropriate data type DBObject object = (DBObject) tr.getTransferData(FileTransferable.DATA_FLAVOR); if (object == null) { return; } // get new parent node Point loc = e.getLocation(); TreePath destinationPath = getPathForLocation(loc.x, loc.y); final String msg = testDropTarget(destinationPath, selectedTreePath, object.getType()); if (msg != null) { e.rejectDrop(); SwingUtilities.invokeLater(new Runnable() { public void run() { JOptionPane.showMessageDialog(Globals.getMainFrame(), msg, "Error Dialog", JOptionPane.ERROR_MESSAGE); } }); return; } DBBrowserNode newParent = (DBBrowserNode) destinationPath.getLastPathComponent(); String newPath = newParent.getDBObject().getAbsolutePath(); // move to root if (newPath == null) { if ((object.getType() == DBObject.QUERIES) || (object.getType() == DBObject.FOLDER_QUERY)) { newPath = new File(FileReportPersistence.CONNECTIONS_DIR + File.separator + DefaultDataSourceManager.getInstance().getConnectedDataSource().getName() + File.separator + FileReportPersistence.QUERIES_FOLDER).getAbsolutePath(); } else if ((object.getType() == DBObject.REPORTS) || (object.getType() == DBObject.FOLDER_REPORT)) { newPath = new File(FileReportPersistence.CONNECTIONS_DIR + File.separator + DefaultDataSourceManager.getInstance().getConnectedDataSource().getName() + File.separator + FileReportPersistence.REPORTS_FOLDER).getAbsolutePath(); } else if ((object.getType() == DBObject.CHARTS) || (object.getType() == DBObject.FOLDER_CHART)) { newPath = new File(FileReportPersistence.CONNECTIONS_DIR + File.separator + DefaultDataSourceManager.getInstance().getConnectedDataSource().getName() + File.separator + FileReportPersistence.CHARTS_FOLDER).getAbsolutePath(); } } // get old parent node DBBrowserNode oldParent = (DBBrowserNode) getSelectedNode().getParent(); int action = e.getDropAction(); boolean copyAction = (action == DnDConstants.ACTION_COPY); // make new child node String oldAbsolutePath = getSelectedNode().getDBObject().getAbsolutePath(); DBObject newObject = new DBObject(object.getName(), object.getSchemaName(), object.getType()); String newAbsolutePath = newPath; if (object.getType() == DBObject.QUERIES) { newAbsolutePath = newAbsolutePath + File.separator + object.getName() + FileReportPersistence.REPORT_EXTENSION_SEPARATOR + FileReportPersistence.REPORT_EXTENSION; } else if (object.getType() == DBObject.REPORTS) { newAbsolutePath = newAbsolutePath + File.separator + object.getName() + FormSaver.REPORT_FULL_EXTENSION; } else if (object.getType() == DBObject.CHARTS) { newAbsolutePath = newAbsolutePath + File.separator + object.getName() + ChartUtil.CHART_FULL_EXTENSION; } else { // folder newAbsolutePath = newAbsolutePath + File.separator + object.getName(); } newObject.setAbsolutePath(newAbsolutePath); DBBrowserNode newChild = new DBBrowserNode(newObject); if ((object.getType() == DBObject.FOLDER_QUERY) || (object.getType() == DBObject.FOLDER_REPORT) || (object.getType() == DBObject.FOLDER_CHART)) { newChild.setAllowsChildren(true); } else { newChild.setAllowsChildren(false); } try { boolean overwrite = false; if (new File(newObject.getAbsolutePath()).exists()) { String message; if (object.getType() == DBObject.QUERIES) { message = I18NSupport.getString("import.query.exists", object.getName()); int option = JOptionPane.showConfirmDialog(Globals.getMainFrame(), message, "", JOptionPane.YES_NO_OPTION); if (option != JOptionPane.YES_OPTION) { return; } else { overwrite = true; } } else if (object.getType() == DBObject.REPORTS) { message = I18NSupport.getString("import.report.exists", object.getName()); int option = JOptionPane.showConfirmDialog(Globals.getMainFrame(), message, "", JOptionPane.YES_NO_OPTION); if (option != JOptionPane.YES_OPTION) { return; } else { overwrite = true; } } else if (object.getType() == DBObject.CHARTS) { message = I18NSupport.getString("import.chart.exists", object.getName()); int option = JOptionPane.showConfirmDialog(Globals.getMainFrame(), message, "", JOptionPane.YES_NO_OPTION); if (option != JOptionPane.YES_OPTION) { return; } else { overwrite = true; } } else { message = I18NSupport.getString("folder.add.exists", object.getName()); Show.info(message); return; } } boolean save = true; Report report = null; Chart chart = null; ReportPersistence repPersist = ReportPersistenceFactory .createReportPersistence(Globals.getReportPersistenceType()); File newFile = new File(newAbsolutePath); if (!object.isFolder()) { if ((object.getType() == DBObject.REPORTS) || (object.getType() == DBObject.QUERIES)) { report = ReportUtil.loadConvertedReport(new FileInputStream(object.getAbsolutePath())); } else if (object.getType() == DBObject.CHARTS) { chart = ChartUtil.loadChart(new FileInputStream(object.getAbsolutePath())); } } if (object.getType() == DBObject.QUERIES) { save = repPersist.saveReport(report, newObject.getAbsolutePath()); } else if (object.getType() == DBObject.REPORTS) { save = FormSaver.getInstance().save(newFile, report); try { FileUtil.copyImages(report, newFile.getParentFile()); } catch (IOException ex) { LOG.error(ex.getMessage(), ex); } } else if (object.getType() == DBObject.CHARTS) { save = ChartUtil.save(newFile, chart); } else { newFile.mkdirs(); FileUtil.copyDirToDir(new File(object.getAbsolutePath()), newFile); } if (save) { if (!copyAction) { // delete is the same for query and report(delete // the file) if (object.isFolder()) { FileUtil.deleteDir(new File(oldAbsolutePath)); } else { repPersist.deleteReport(oldAbsolutePath); } oldParent.remove(getSelectedNode()); // if we move the current loaded query/report take // care to update // the path in Globals if (object.getType() == DBObject.QUERIES) { if (oldAbsolutePath.equals(Globals.getCurrentQueryAbsolutePath())) { Globals.setCurrentQueryAbsolutePath(newAbsolutePath); } } else if (object.getType() == DBObject.REPORTS) { if (oldAbsolutePath.equals(Globals.getCurrentReportAbsolutePath())) { Globals.setCurrentReportAbsolutePath(newAbsolutePath); } } else if (object.getType() == DBObject.CHARTS) { if (oldAbsolutePath.equals(Globals.getCurrentChartAbsolutePath())) { Globals.setCurrentChartAbsolutePath(newAbsolutePath); } } else { String qPath = Globals.getCurrentQueryAbsolutePath(); String rPath = Globals.getCurrentReportAbsolutePath(); String cPath = Globals.getCurrentChartAbsolutePath(); if ((qPath != null) && qPath.startsWith(oldAbsolutePath)) { String newQPath = newAbsolutePath + File.separator + qPath.substring(oldAbsolutePath.length() + 1); Globals.setCurrentQueryAbsolutePath(newQPath); } else if ((rPath != null) && rPath.startsWith(oldAbsolutePath)) { String newRPath = newAbsolutePath + File.separator + rPath.substring(oldAbsolutePath.length() + 1); Globals.setCurrentReportAbsolutePath(newRPath); } else if ((cPath != null) && cPath.startsWith(oldAbsolutePath)) { String newCPath = newAbsolutePath + File.separator + cPath.substring(oldAbsolutePath.length() + 1); Globals.setCurrentChartAbsolutePath(newCPath); } } } boolean expand = expandNode(newParent, false); // if node was not expanded (expand==true) we do not // need to add the node // because this is done by the nod expander (see that // report was saved through // saveReport previously!) if (!expand) { if (object.isFolder()) { insertFolder(newParent, newChild); } else { if (!overwrite) { insertFile(newParent, newChild); } } } } if (copyAction) { e.acceptDrop(DnDConstants.ACTION_COPY); } else { e.acceptDrop(DnDConstants.ACTION_MOVE); } } catch (java.lang.IllegalStateException ils) { e.rejectDrop(); } e.getDropTargetContext().dropComplete(true); // expand nodes appropriately - this probably isnt the best // way... DefaultTreeModel model = (DefaultTreeModel) getModel(); model.reload(oldParent); model.reload(newParent); TreePath parentPath = new TreePath(newParent.getPath()); expandPath(parentPath); } catch (IOException io) { io.printStackTrace(); e.rejectDrop(); } catch (UnsupportedFlavorException ufe) { ufe.printStackTrace(); e.rejectDrop(); } } public DBBrowserNode getSelectedNode() { return selectedNode; } /** * Convenience method to test whether drop location is valid * * @param destination * The destination path * @param dropper * The path for the node to be dropped * @param type * object data type * @return null if no problems, otherwise an explanation */ private String testDropTarget(TreePath destination, TreePath dropper, byte type) { boolean destinationPathIsNull = destination == null; if (destinationPathIsNull) { return "Invalid drop location."; } DBBrowserNode node = (DBBrowserNode) destination.getLastPathComponent(); if (!node.getAllowsChildren()) { return "This node does not allow children"; } if (destination.equals(dropper)) { return "Destination cannot be same as source"; } if (dropper.isDescendant(destination)) { return "Destination node cannot be a descendant."; } if (dropper.getParentPath().equals(destination)) { return "Destination node cannot be a parent."; } if ((type == DBObject.QUERIES) || (type == DBObject.FOLDER_QUERY)) { if ((node.getDBObject().getType() != DBObject.FOLDER_QUERY) && (node.getDBObject().getType() != DBObject.QUERIES_GROUP)) { return "No query folder"; } } else if ((type == DBObject.REPORTS) || (type == DBObject.FOLDER_REPORT)) { if ((node.getDBObject().getType() != DBObject.FOLDER_REPORT) && (node.getDBObject().getType() != DBObject.REPORTS_GROUP)) { return "No report folder"; } } else if ((type == DBObject.CHARTS) || (type == DBObject.FOLDER_CHART)) { if ((node.getDBObject().getType() != DBObject.FOLDER_CHART) && (node.getDBObject().getType() != DBObject.CHARTS_GROUP)) { return "No chart folder"; } } else { return "No folder"; } return null; } /** * TreeSelectionListener - sets selected node */ public void valueChanged(TreeSelectionEvent evt) { selectedTreePath = evt.getNewLeadSelectionPath(); if (selectedTreePath == null) { selectedNode = null; return; } selectedNode = (DBBrowserNode) selectedTreePath.getLastPathComponent(); } } class DBBrowserTreeDragSourceListener extends DragSourceAdapter { public void dragEnter(DragSourceDragEvent dsde) { if ((dsde.getDropAction() & DnDConstants.ACTION_MOVE) == DnDConstants.ACTION_MOVE) { dsde.getDragSourceContext().setCursor(DragSource.DefaultLinkDrop); } else { dsde.getDragSourceContext().setCursor(DragSource.DefaultLinkNoDrop); } } public void dragExit(DragSourceEvent dse) { dse.getDragSourceContext().setCursor(DragSource.DefaultLinkNoDrop); } } class DBBrowserTreeReportDragSourceListener extends DragSourceAdapter { public void dragEnter(DragSourceDragEvent dsde) { setCursor(dsde); } public void dragExit(DragSourceEvent dse) { dse.getDragSourceContext().setCursor(DragSource.DefaultMoveNoDrop); } private void setCursor(DragSourceDragEvent dsde) { int action = dsde.getDropAction(); // @todo ACTION_NONE must be removed : but somehow no action is // passed here for ACTION_COPY if ((action == DnDConstants.ACTION_COPY) || (action == DnDConstants.ACTION_NONE)) { // if (action == DnDConstants.ACTION_COPY) { dsde.getDragSourceContext().setCursor(DragSource.DefaultCopyDrop); } else { if (action == DnDConstants.ACTION_MOVE) { dsde.getDragSourceContext().setCursor(DragSource.DefaultMoveDrop); } else { dsde.getDragSourceContext().setCursor(DragSource.DefaultMoveNoDrop); } } } } }