001: /*
002: * SQLeonardo :: java database frontend
003: * Copyright (C) 2004 nickyb@users.sourceforge.net
004: *
005: * This program is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU General Public License
007: * as published by the Free Software Foundation; either version 2
008: * of the License, or (at your option) any later version.
009: *
010: * This program is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
013: * GNU General Public License for more details.
014: *
015: * You should have received a copy of the GNU General Public License
016: * along with this program; if not, write to the Free Software
017: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
018: *
019: */
020:
021: package nickyb.sqleonardo.querybuilder;
022:
023: import java.awt.event.ComponentAdapter;
024: import java.awt.event.ComponentEvent;
025: import java.io.IOException;
026: import java.sql.Connection;
027: import java.sql.SQLException;
028:
029: import javax.swing.JOptionPane;
030: import javax.swing.JSplitPane;
031: import javax.swing.JTabbedPane;
032: import javax.swing.event.ChangeEvent;
033: import javax.swing.event.ChangeListener;
034:
035: import nickyb.sqleonardo.common.gui.*;
036: import nickyb.sqleonardo.common.gui.BorderLayoutPanel;
037: import nickyb.sqleonardo.common.util.I18n;
038: import nickyb.sqleonardo.querybuilder.syntax.QueryTokens;
039: import nickyb.sqleonardo.querybuilder.syntax.SQLParser;
040:
041: public class QueryBuilder extends JTabbedPane implements ChangeListener {
042: private boolean loading = false;
043:
044: public static boolean autoJoin = true;
045: public static boolean autoAlias = true;
046: public static boolean useAlwaysQuote = true;
047:
048: /* querybuilder.objetctype.TABLE */
049: public static boolean loadObjectsAtOnce = true;
050: public static boolean selectAllColumns = true;
051:
052: public static String identifierQuoteString = "\"";
053: public static int maxColumnNameLength = 0;
054:
055: private Connection connection;
056: private QueryModel model = new QueryModel();
057:
058: private TextView syntax;
059:
060: ViewBrowser browser;
061: ViewDiagram diagram;
062: ViewObjects objects;
063:
064: public QueryBuilder() {
065: this (null);
066: }
067:
068: public QueryBuilder(Connection connection) {
069: super (JTabbedPane.BOTTOM);
070:
071: QueryActions.init(this );
072:
073: this .initComponents();
074: this .setConnection(connection);
075:
076: this .addComponentListener(new ComponentAdapter() {
077: public void componentResized(ComponentEvent evt) {
078: BorderLayoutPanel designer = (BorderLayoutPanel) QueryBuilder.this
079: .getComponentAt(0);
080: JSplitPane split = (JSplitPane) designer
081: .getComponent(0);
082: JSplitPane split2 = (JSplitPane) split
083: .getLeftComponent();
084: // Value changed to 0.5 by Giulio Toffoli
085: split2.setDividerLocation(0.5);
086: split2.validate();
087: }
088: });
089:
090: this .transferFocus();
091: }
092:
093: private void initComponents() {
094: browser = new ViewBrowser(this );
095: diagram = new ViewDiagram(this );
096: objects = new ViewObjects(this );
097:
098: JSplitPane split2 = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
099: split2.setOneTouchExpandable(true);
100: split2.setDividerLocation(250);
101: split2.setLeftComponent(browser);
102: split2.setRightComponent(objects);
103:
104: JSplitPane split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
105: split.setTopComponent(split2);
106: split.setBottomComponent(diagram);
107: split.setOneTouchExpandable(true);
108:
109: BorderLayoutPanel designer = new BorderLayoutPanel(2, 2);
110: designer.setComponentCenter(split);
111:
112: add(I18n.getString("querybuilder.designer", "designer"),
113: designer);
114: add(I18n.getString("querybuilder.syntax", "syntax"),
115: syntax = new TextView(new QueryStyledDocument()));
116: addChangeListener(this );
117: }
118:
119: public boolean isDragAndDropEnabled() {
120: return diagram.isDragAndDropEnabled();
121: }
122:
123: public void setDragAndDropEnabled(boolean b) {
124: diagram.setDragAndDropEnabled(b);
125: }
126:
127: public QueryModel getQueryModel() {
128: return model;
129: }
130:
131: public void setQueryModel(QueryModel qm) {
132: loading = true;
133:
134: model = qm;
135: diagram.onModelChanged();
136: browser.onModelChanged();
137: objects.onModelChanged();
138:
139: loading = false;
140: }
141:
142: boolean isLoading() {
143: return loading;
144: }
145:
146: public Connection getConnection() {
147: return connection;
148: }
149:
150: public void setConnection(Connection connection) {
151: try {
152: this .connection = connection;
153:
154: if (connection != null) {
155: QueryBuilder.identifierQuoteString = connection
156: .getMetaData().getIdentifierQuoteString();
157: QueryBuilder.maxColumnNameLength = connection
158: .getMetaData().getMaxColumnNameLength();
159: }
160:
161: objects.onConnectionChanged();
162: } catch (SQLException sqle) {
163: System.out.println("[ QueryBuilder::setConnection ]\n"
164: + sqle);
165: }
166: }
167:
168: void onLoad() {
169: loading = true;
170:
171: load(browser.getQuerySpecification().getFromClause());
172: load(browser.getQuerySpecification().getSelectList());
173:
174: loading = false;
175: }
176:
177: private void load(QueryTokens._Expression[] tokens) {
178: for (int i = 0; i < tokens.length; i++) {
179: if (tokens[i] instanceof QueryTokens.Column) {
180: QueryTokens.Column token = (QueryTokens.Column) tokens[i];
181:
182: DiagramEntity entity = diagram.getEntity(token
183: .getTable());
184: if (entity != null) {
185: DiagramField field = entity.getField(token
186: .getName());
187: if (field != null)
188: field.setQueryToken(token);
189: }
190: }
191: }
192: }
193:
194: private void load(QueryTokens._TableReference[] tokens) {
195: for (int i = 0; i < tokens.length; i++) {
196: if (tokens[i] instanceof QueryTokens.Table) {
197: DiagramLoader.run(DiagramLoader.DEFAULT, this ,
198: (QueryTokens.Table) tokens[i], false);
199: } else {
200: QueryTokens.Join token = (QueryTokens.Join) tokens[i];
201:
202: DiagramEntity entityP = diagram.getEntity(token
203: .getPrimary().getTable());
204: if (entityP == null) {
205: DiagramLoader.run(DiagramLoader.DEFAULT, this ,
206: token.getPrimary().getTable(), false);
207: entityP = diagram.getEntity(token.getPrimary()
208: .getTable());
209: }
210:
211: DiagramEntity entityF = diagram.getEntity(token
212: .getForeign().getTable());
213: if (entityF == null) {
214: DiagramLoader.run(DiagramLoader.DEFAULT, this ,
215: token.getForeign().getTable(), false);
216: entityF = diagram.getEntity(token.getForeign()
217: .getTable());
218: }
219:
220: DiagramField fieldP = entityP.getField(token
221: .getPrimary().getName());
222: DiagramField fieldF = entityF.getField(token
223: .getForeign().getName());
224:
225: if (fieldP != null && fieldF != null) {
226: diagram.join(entityP, fieldP);
227: diagram.join(entityF, fieldF);
228:
229: DiagramRelation relation = diagram
230: .getRelation(token);
231: if (relation != null)
232: relation.setQueryToken(token);
233: }
234: }
235: }
236: }
237:
238: public void stateChanged(ChangeEvent ce) {
239: this .getActionMap().get(QueryActions.ENTITIES_ARRANGE)
240: .setEnabled(this .getSelectedIndex() == 0);
241: this .getActionMap().get(QueryActions.ENTITIES_REMOVE)
242: .setEnabled(this .getSelectedIndex() == 0);
243: this .getActionMap().get(QueryActions.ENTITIES_PACK).setEnabled(
244: this .getSelectedIndex() == 0);
245:
246: if (this .getSelectedIndex() == 0) {
247: String msql = model.toString(true);
248: String tsql = syntax.getText();
249:
250: if (!tsql.equals(msql)) {
251: int choice = JOptionPane
252: .showConfirmDialog(
253: this ,
254: I18n
255: .getString(
256: "querybuilder.syntaxChanged",
257: "syntax changed!\ndo you want to apply changes (designer need to reload)?"));
258: if (choice == JOptionPane.YES_OPTION) {
259: // this thread resolve: IllegalComponentStateException
260: new Thread(new Runnable() {
261: public void run() {
262: while (!QueryBuilder.this .getComponentAt(0)
263: .isVisible())
264: ;
265: try {
266: QueryModel qm = SQLParser
267: .toQueryModel(syntax.getText());
268: qm.setSchema(QueryBuilder.this .model
269: .getSchema());
270: QueryBuilder.this .setQueryModel(qm);
271: } catch (IOException e) {
272: }
273: }
274: }).start();
275: }
276: }
277: } else
278: syntax.setText(this .getQueryModel().toString(true));
279: }
280: }
|