Author: thomasobrien95
Date: Wed May 20 15:30:41 2009
New Revision: 3059
Added:
trunk/src/ca/sqlpower/architect/swingui/olap/ViewEntryPanel.java
Modified:
trunk/src/ca/sqlpower/architect/swingui/olap/CubeEditPanel.java
trunk/src/ca/sqlpower/architect/swingui/olap/JoinEntryPanel.java
Log:
More work on the join and view entry panels.
-Refactored the ViewEntryPanel to its own class as it makes more sense.
-If cycles exist in the JoinEntryPanel that cannot be created in
the Mondrian join XML language then the user will be promted if they
want a view created from the current joins defined instead.
-This needs a fix to the Query class in the library to work correctly.
-Updated the QueryData class to be named Query as it was changed in
the library to reduce confusion.
Modified: trunk/src/ca/sqlpower/architect/swingui/olap/CubeEditPanel.java
==============================================================================
--- trunk/src/ca/sqlpower/architect/swingui/olap/CubeEditPanel.java
(original)
+++ trunk/src/ca/sqlpower/architect/swingui/olap/CubeEditPanel.java Wed May
20 15:30:41 2009
@@ -19,7 +19,6 @@
package ca.sqlpower.architect.swingui.olap;
-import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.List;
@@ -36,14 +35,10 @@
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
-import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
-import javax.swing.JToolBar;
-import javax.swing.tree.TreeModel;
import org.apache.log4j.Logger;
-import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import ca.sqlpower.architect.olap.OLAPSession;
import ca.sqlpower.architect.olap.OLAPUtil;
@@ -54,18 +49,12 @@
import ca.sqlpower.architect.olap.MondrianModel.SQL;
import ca.sqlpower.architect.olap.MondrianModel.Table;
import ca.sqlpower.architect.olap.MondrianModel.View;
-import ca.sqlpower.architect.swingui.ArchitectSwingSession;
-import ca.sqlpower.architect.swingui.DBTree;
import ca.sqlpower.architect.swingui.PlayPen;
-import ca.sqlpower.architect.swingui.dbtree.DBTreeModel;
import ca.sqlpower.sqlobject.SQLDatabase;
import ca.sqlpower.sqlobject.SQLDatabaseMapping;
import ca.sqlpower.sqlobject.SQLObjectException;
-import ca.sqlpower.sqlobject.SQLObjectRoot;
import ca.sqlpower.sqlobject.SQLTable;
-import ca.sqlpower.swingui.DataEntryPanel;
import ca.sqlpower.swingui.DataEntryPanelBuilder;
-import ca.sqlpower.swingui.query.SQLQueryUIComponents;
import ca.sqlpower.validation.Validator;
import ca.sqlpower.validation.swingui.FormValidationHandler;
import ca.sqlpower.validation.swingui.StatusComponent;
@@ -79,107 +68,6 @@
private static final Logger logger =
Logger.getLogger(CubeEditPanel.class);
- /**
- * This entry panel will create a view builder based on the
- * SQLQueryUIComponents in the library.
- */
- private class ViewEntryPanel implements DataEntryPanel {
-
- /**
- * The main panel of this data entry panel
- */
- private JSplitPane splitPane;
-
- /**
- * The text area users will enter a select statement into.
- */
- private RSyntaxTextArea queryArea;
-
- /**
- * The query components used to create the view. This needs
- * to be closed when the entry panel goes away or else connections
- * will be leaked.
- */
- private SQLQueryUIComponents queryComponents;
-
- public ViewEntryPanel(ArchitectSwingSession session) {
- DefaultFormBuilder builder = new DefaultFormBuilder(new
FormLayout("pref, 5dlu:grow, pref, 3dlu, pref", "pref, fill:pref:grow"));
-
- SQLDatabase db = getDatabase();
- queryComponents = new SQLQueryUIComponents(session,
session.getContext().getPlDotIni(), session, builder.getPanel());
-
queryComponents.getRowLimitSpinner().setValue(Integer.valueOf(1000));
-
queryComponents.getDatabaseComboBox().setSelectedItem(db.getDataSource());
-
- JToolBar toolbar = new JToolBar();
- toolbar.add(queryComponents.getPrevQueryButton());
- toolbar.add(queryComponents.getNextQueryButton());
- toolbar.addSeparator();
- toolbar.add(queryComponents.getExecuteButton());
- toolbar.add(queryComponents.getStopButton());
- toolbar.add(queryComponents.getClearButton());
- toolbar.addSeparator();
- toolbar.add(queryComponents.getUndoButton());
- toolbar.add(queryComponents.getRedoButton());
- toolbar.addSeparator();
- toolbar.add(new JLabel(db.getName()));
- builder.append(toolbar);
- builder.append("Row Limit",
queryComponents.getRowLimitSpinner());
- builder.nextLine();
-
- queryArea = queryComponents.getQueryArea();
- builder.append(new JScrollPane(queryArea), 5);
- queryArea.setText(selectStatements.getText());
-
- JSplitPane rightSplitPane = new
JSplitPane(JSplitPane.VERTICAL_SPLIT);
- rightSplitPane.setTopComponent(builder.getPanel());
-
rightSplitPane.setBottomComponent(queryComponents.getResultTabPane());
- rightSplitPane.setPreferredSize(new Dimension((int)
Math.max(400, rightSplitPane.getPreferredSize().getWidth()), (int)
Math.max(500, rightSplitPane.getPreferredSize().getHeight())));
- rightSplitPane.setResizeWeight(0.5);
-
- SQLObjectRoot root = new SQLObjectRoot();
- TreeModel treeModel;
- DBTree tree;
- try {
- root.addChild(db);
- treeModel = new DBTreeModel(root);
- tree = new DBTree(session);
- } catch (SQLObjectException e) {
- throw new RuntimeException(e);
- }
- tree.setModel(treeModel);
- tree.setPopupMenuEnabled(false);
-
- splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
- splitPane.setLeftComponent(tree);
- splitPane.setRightComponent(rightSplitPane);
- splitPane.setResizeWeight(0.2);
-
- }
-
- public boolean applyChanges() {
- selectStatements.setText(queryArea.getText());
- cleanup();
- return true;
- }
-
- public void discardChanges() {
- cleanup();
- }
-
- private void cleanup() {
- queryComponents.closingDialogOwner();
- }
-
- public JComponent getPanel() {
- return splitPane;
- }
-
- public boolean hasUnsavedChanges() {
- return true;
- }
-
- }
-
private final Cube cube;
private final JPanel panel;
private JTextField nameField;
@@ -243,7 +131,7 @@
final JButton viewEditButton = new JButton(new
AbstractAction("Edit...") {
public void actionPerformed(ActionEvent e) {
logger.debug("The dialog owner is " +
playPen.getDialogOwner());
- JDialog dialog =
DataEntryPanelBuilder.createDataEntryPanelDialog(new
ViewEntryPanel(playPen.getSession()), playPen.getDialogOwner(), "View
Builder", "OK");
+ JDialog dialog =
DataEntryPanelBuilder.createDataEntryPanelDialog(new
ViewEntryPanel(playPen.getSession(), getDatabase(), CubeEditPanel.this),
playPen.getDialogOwner(), "View Builder", "OK");
dialog.pack();
dialog.setVisible(true);
}
@@ -317,8 +205,17 @@
viewRadioButton.doClick();
tableRadioButton.setEnabled(false);
tableChooser.setEnabled(false);
- for (SQL sql : ((View) cube.getFact()).getSelects()) {
- selectStatements.append(sql.getText() + "\n");
+
+ //XXX There could be multiple SQL objects in a view but we can
only edit one at a time right now.
+ final List<SQL> selects = ((View) cube.getFact()).getSelects();
+ for (SQL sql : selects) {
+ if (sql.getDialect() == null ||
sql.getDialect().equals("generic")) {
+ selectStatements.append(sql.getText());
+ break;
+ }
+ }
+ if (selectStatements.getText().trim().length() == 0
&& !selects.isEmpty()) {
+ selectStatements.append(selects.get(0).getText());
}
} else if (tables.isEmpty()) {
tableChooser.addItem("Database has no tables");
@@ -432,5 +329,17 @@
public Join getJoinFact() {
return joinFact;
+ }
+
+ public String getSelectText() {
+ return selectStatements.getText();
+ }
+
+ public void setSelectText(String text) {
+ selectStatements.setText(text);
+ }
+
+ public void setViewSelected() {
+ viewRadioButton.doClick();
}
}
Modified: trunk/src/ca/sqlpower/architect/swingui/olap/JoinEntryPanel.java
==============================================================================
--- trunk/src/ca/sqlpower/architect/swingui/olap/JoinEntryPanel.java
(original)
+++ trunk/src/ca/sqlpower/architect/swingui/olap/JoinEntryPanel.java Wed
May 20 15:30:41 2009
@@ -33,6 +33,7 @@
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JLabel;
+import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
@@ -52,7 +53,7 @@
import ca.sqlpower.query.Container;
import ca.sqlpower.query.Item;
import ca.sqlpower.query.ItemContainer;
-import ca.sqlpower.query.QueryData;
+import ca.sqlpower.query.Query;
import ca.sqlpower.query.SQLJoin;
import ca.sqlpower.query.StringItem;
import ca.sqlpower.query.TableContainer;
@@ -113,7 +114,7 @@
}
};
- private final QueryData model;
+ private final Query model;
private final ForumAction forumAction = new ForumAction(new
ImageIcon(JoinEntryPanel.class.getResource("/icons/architect16.png")), "Help
on the forums.");
@@ -131,7 +132,7 @@
this.session = session;
this.db = db;
this.editPanel = editPanel;
- model = new QueryData(session);
+ model = new Query(session);
if (join != null) {
addSQLJoinsToModel(join);
@@ -315,9 +316,11 @@
join = new Join();
//check if the left side is in the map
final Container leftContainer =
sqlJoin.getLeftColumn().getContainer();
+ Join leftExistingJoin = null;
if (tableToJoinMap.containsKey(leftContainer)) {
//if so get the join the left side is involved with and
update the joins in the map accordingly
Join existingJoin = tableToJoinMap.get(leftContainer);
+ leftExistingJoin = existingJoin;
join.setLeftAlias(leftContainer.getName());
join.setLeft(existingJoin);
join.setLeftKey(sqlJoin.getLeftColumn().getName());
@@ -340,6 +343,26 @@
if (tableToJoinMap.containsKey(rightContainer)) {
//if so get the join the right side is involved with and
update the joins in the map accordingly
Join existingJoin = tableToJoinMap.get(rightContainer);
+
+ if (leftExistingJoin != null && leftExistingJoin ==
existingJoin) {
+
+
+ String invalidJoinStatement = "<html>The join
specified contains cycles and cannot be specified in OLAP.\n" +
+ "Either the cycle needs to be broken by dragging in
the same table to duplicate it\n" +
+ "or a view can be created to represent this join
specification.";
+ final String invalidJoinDialogHeader = "Invalid join
specification";
+
+ int retType = JOptionPane.showOptionDialog(panel,
invalidJoinStatement, invalidJoinDialogHeader,
+ JOptionPane.YES_NO_OPTION,
JOptionPane.WARNING_MESSAGE, null,
+ new Object[]{"Create View", "Cancel"}, "Create
View");
+ if (retType == JOptionPane.OK_OPTION) {
+ editPanel.setViewSelected();
+ editPanel.setSelectText(model.generateQuery());
+ return true;
+ } else {
+ return false;
+ }
+ }
join.setRightAlias(rightContainer.getName());
join.setRight(existingJoin);
join.setRightKey(sqlJoin.getRightColumn().getName());
Added: trunk/src/ca/sqlpower/architect/swingui/olap/ViewEntryPanel.java
==============================================================================
--- (empty file)
+++ trunk/src/ca/sqlpower/architect/swingui/olap/ViewEntryPanel.java Wed
May 20 15:30:41 2009
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2009, SQL Power Group Inc.
+ *
+ * This file is part of Power*Architect.
+ *
+ * Power*Architect is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Power*Architect is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package ca.sqlpower.architect.swingui.olap;
+
+import java.awt.Dimension;
+
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JScrollPane;
+import javax.swing.JSplitPane;
+import javax.swing.JToolBar;
+import javax.swing.tree.TreeModel;
+
+import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
+
+import ca.sqlpower.architect.swingui.ArchitectSwingSession;
+import ca.sqlpower.architect.swingui.DBTree;
+import ca.sqlpower.architect.swingui.dbtree.DBTreeModel;
+import ca.sqlpower.sqlobject.SQLDatabase;
+import ca.sqlpower.sqlobject.SQLObjectException;
+import ca.sqlpower.sqlobject.SQLObjectRoot;
+import ca.sqlpower.swingui.DataEntryPanel;
+import ca.sqlpower.swingui.query.SQLQueryUIComponents;
+
+import com.jgoodies.forms.builder.DefaultFormBuilder;
+import com.jgoodies.forms.layout.FormLayout;
+
+/**
+ * This entry panel will create a view builder based on the
+ * SQLQueryUIComponents in the library.
+ */
+class ViewEntryPanel implements DataEntryPanel {
+
+ /**
+ * The main panel of this data entry panel
+ */
+ private JSplitPane splitPane;
+
+ /**
+ * The text area users will enter a select statement into.
+ */
+ private RSyntaxTextArea queryArea;
+
+ /**
+ * The query components used to create the view. This needs
+ * to be closed when the entry panel goes away or else connections
+ * will be leaked.
+ */
+ private SQLQueryUIComponents queryComponents;
+
+ private final CubeEditPanel cubeEditPanel;
+
+ public ViewEntryPanel(ArchitectSwingSession session, SQLDatabase db,
CubeEditPanel cubeEditPanel) {
+ this.cubeEditPanel = cubeEditPanel;
+ DefaultFormBuilder builder = new DefaultFormBuilder(new
FormLayout("pref, 5dlu:grow, pref, 3dlu, pref", "pref, fill:pref:grow"));
+
+ queryComponents = new SQLQueryUIComponents(session,
session.getContext().getPlDotIni(), session, builder.getPanel());
+
queryComponents.getRowLimitSpinner().setValue(Integer.valueOf(1000));
+
queryComponents.getDatabaseComboBox().setSelectedItem(db.getDataSource());
+
+ JToolBar toolbar = new JToolBar();
+ toolbar.add(queryComponents.getPrevQueryButton());
+ toolbar.add(queryComponents.getNextQueryButton());
+ toolbar.addSeparator();
+ toolbar.add(queryComponents.getExecuteButton());
+ toolbar.add(queryComponents.getStopButton());
+ toolbar.add(queryComponents.getClearButton());
+ toolbar.addSeparator();
+ toolbar.add(queryComponents.getUndoButton());
+ toolbar.add(queryComponents.getRedoButton());
+ toolbar.addSeparator();
+ toolbar.add(new JLabel(db.getName()));
+ builder.append(toolbar);
+ builder.append("Row Limit", queryComponents.getRowLimitSpinner());
+ builder.nextLine();
+
+ queryArea = queryComponents.getQueryArea();
+ builder.append(new JScrollPane(queryArea), 5);
+ queryArea.setText(cubeEditPanel.getSelectText());
+
+ JSplitPane rightSplitPane = new
JSplitPane(JSplitPane.VERTICAL_SPLIT);
+ rightSplitPane.setTopComponent(builder.getPanel());
+
rightSplitPane.setBottomComponent(queryComponents.getResultTabPane());
+ rightSplitPane.setPreferredSize(new Dimension((int) Math.max(400,
rightSplitPane.getPreferredSize().getWidth()), (int) Math.max(500,
rightSplitPane.getPreferredSize().getHeight())));
+ rightSplitPane.setResizeWeight(0.5);
+
+ SQLObjectRoot root = new SQLObjectRoot();
+ TreeModel treeModel;
+ DBTree tree;
+ try {
+ root.addChild(db);
+ treeModel = new DBTreeModel(root);
+ tree = new DBTree(session);
+ } catch (SQLObjectException e) {
+ throw new RuntimeException(e);
+ }
+ tree.setModel(treeModel);
+ tree.setPopupMenuEnabled(false);
+
+ splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
+ splitPane.setLeftComponent(tree);
+ splitPane.setRightComponent(rightSplitPane);
+ splitPane.setResizeWeight(0.2);
+
+ }
+
+ public boolean applyChanges() {
+ cubeEditPanel.setSelectText(queryArea.getText());
+ cleanup();
+ return true;
+ }
+
+ public void discardChanges() {
+ cleanup();
+ }
+
+ private void cleanup() {
+ queryComponents.closingDialogOwner();
+ }
+
+ public JComponent getPanel() {
+ return splitPane;
+ }
+
+ public boolean hasUnsavedChanges() {
+ return true;
+ }
+
+}
\ No newline at end of file