0001: /** @author: Rahul Kumar $Author: rahul_kumar $
0002: * $Id: SQLForm.java,v 1.9 2004/02/01 07:49:24 rahul_kumar Exp rahul $
0003: * Descr: SQL Plus like utility with auto-completion from data dictionary
0004: * The autocompletion has not been worked, but one can pick and construct.
0005: * Environment: JDK 1.3, uses swing classes
0006: * Dates: 13 Mar 1999
0007: * @version 1.0
0008: * Uses mysql.ini for DSN name, UID and PWD
0009: * This is opensource and free and is under the GNU License.
0010: */package isql;
0011:
0012: import javax.swing.*;
0013:
0014: import java.awt.Container;
0015: import java.awt.Dimension;
0016: import java.util.List;
0017: import java.awt.*;
0018:
0019: import java.awt.event.ContainerEvent;
0020: import java.awt.event.ContainerListener;
0021: import java.awt.event.ActionEvent;
0022: import java.awt.event.ActionListener;
0023: import javax.swing.event.ListSelectionEvent;
0024: import javax.swing.event.ListSelectionListener;
0025: import java.sql.*;
0026: import java.util.*; //import SQLTabbedPane;
0027: //import SQLColumnList;
0028: //import ScrollList;
0029: //import SQLODBC;
0030: import javax.swing.JOptionPane;
0031: import java.awt.event.WindowEvent; // added 20011013
0032: import java.awt.event.WindowAdapter; // added 20011013
0033: import javax.swing.*;
0034: import javax.swing.table.*;
0035: import java.io.BufferedWriter;
0036: import java.io.FileWriter;
0037: import java.io.BufferedReader;
0038: import java.io.FileReader;
0039: import java.io.FileNotFoundException;
0040: import java.awt.Component;
0041: import java.awt.Font;
0042: import util.*;
0043:
0044: /** The main class that creates everything else.
0045: */
0046: public class SQLForm extends JFrame implements ContainerListener,
0047: ActionListener {
0048: public static final boolean DEBUG = false;
0049: //JPanel buttonPanel ;
0050: JToolBar buttonPanel;
0051: JMenuBar menubar;
0052: JMenu menu;
0053: JMenu menuMetaData, menuFrameData, menuTableData, menuListData;
0054: JMenu menuBookmark;
0055: JMenu menuConnection = null;
0056: // splitpane is between table and column panel
0057: // maipane is between tabbedpane and splitpane
0058: // fullpane is between mainpane and messagearea
0059: JSplitPane splitPane, mainPane, fullPane, inpPane;
0060: JButton runButton, clearButton, exitButton, connectButton,
0061: constructButton, metaButton;
0062: JButton runSelectedButton;
0063: public SQLTabbedPane tp; // made public after we created commands
0064: JList tablePanel, columnPanel;
0065: JScrollPane tableScroll, columnScroll;
0066: JScrollPane inpPanel;
0067: public JTextArea jtError, jtInput;
0068: //JPopupMenu _popup;
0069: // relates to Buttons
0070: static final String RUN = "run";
0071: static final String EXIT = "exit";
0072: static final String CLEAR = "clear";
0073: static final String CONNECT = "connect";
0074: static final String COPY = "copy";
0075: static final String META = "meta";
0076: static final String CONSTRUCT = "construct";
0077: static final String RUN_SELECTED = "run_selected";
0078: static final String SHOWDATA = "show-data";
0079: /** class that does the database work */
0080: public SQLJDBC myjdbc; // made public after commands was created.
0081: //ArrayList SQLVect;
0082: /** the last SQl executed */
0083: public String _currentSQL;
0084: String[] args;
0085: /** a hash of all the actions, for reusing them. */
0086: private Map htActions = new HashMap();
0087:
0088: /** class that reads up the initialization file */
0089: ReadTNS TNS;
0090: /** contains parameters read from initialization file */
0091: Map htParams;
0092: /** bookmarks loaded statically with connect */
0093: Map htBookmarks;
0094: /** bookmarks loaded dynamically with load */
0095: Map htDynBookmarks;
0096: /** links to be used with construct */
0097: Map htLinks;
0098: /** default sorts to be used when constructing */
0099: Map htSorts;
0100: /** map containing values to be remembered.
0101: * RK added on 20031226 15:26:54
0102: */
0103: Map htMaster;
0104: Map htRemembered;
0105: Map htFilters;
0106: public SmartDocument sd, sd1;
0107: /** Manages key bindings to widgets.
0108: * refactored from readtns.
0109: * RK added on 20031228 20:03:16
0110: * */
0111: Bindings bindings;
0112: /** name of the ini file used by sqlminus, updated in readParams.
0113: */
0114: String inifile = "mysql.ini";
0115:
0116: /** the commandhandler which registers and executes all commands.
0117: */
0118: CommandHandler _commandHandler;
0119:
0120: public SQLForm(String[] ARGS) {
0121: super (
0122: "SQLMinus 1.1.12 [Seawolf] (c) Rahul Kumar, 1998,99. Freeware. rahul_kumar@yahoo.com");
0123: args = ARGS;
0124: //System.out.println("top input + help alt-h version + dyn bookmark");
0125: System.out
0126: .println("version : search and sort columns in jtables.");
0127: //System.out.println(" + read keys from ini file.");
0128: System.out
0129: .println(" + smart link alt-shift-d and ?, prompt for link, regex searches, paging of tables, dynamic menus, new-connection, commands refactored, date substitutin and variable processing, background sqls.");
0130: /*
0131: try {
0132: UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
0133: } catch (Exception exc) {
0134: System.out.println("Error loading L&F: " + exc);
0135: }
0136: */
0137: this .getAccessibleContext().setAccessibleDescription(
0138: "An SQL Client that strives to suck less");
0139:
0140: readParams();
0141: if (DEBUG)
0142: System.out.print(" read params. ");
0143: init();
0144: tp.setAbbreviationTable(TNS.getAbbreviations());
0145: sd1.setAbbreviationTable(TNS.getAbbreviations());
0146: // RK added on 20040201 13:17:43
0147: // initialize the command handler. Hope this is not too late.
0148: _commandHandler = new CommandHandler(this );
0149: _commandHandler.registerAllCommands();
0150: if (args.length == 2) { // not removing due to backward compat
0151: if ("connect".equals(args[1])) {
0152: System.out.print("Connecting..");
0153: connectAction();
0154: }
0155: } else if ("on".equalsIgnoreCase(getAttribute("autoconnect",
0156: "off"))) {
0157: System.out.print("Auto Connecting..");
0158: connectAction();
0159: }
0160: }
0161:
0162: /** initializes the screen */
0163: public void init() {
0164:
0165: if (SQLForm.DEBUG)
0166: System.out.print(" Creating tabbed pane and document. ");
0167: String[] tlabels = { "tables ", " ", " ", " ", " " };
0168: String[] clabels = { "columns ", " ", " ", " ", " " };
0169: //Create all the components.
0170: tp = new SQLTabbedPane(this ); // temporarily passing for keybindings
0171:
0172: sd = new SmartDocument();
0173: sd1 = new SmartDocument();
0174: sd.setParams(htParams);
0175: sd1.setParams(htParams);
0176: tp.setDocument(sd);
0177:
0178: tablePanel = new JList(tlabels);
0179: columnPanel = new JList(clabels);
0180:
0181: if (DEBUG)
0182: System.out.print(" Creating hash for actions. ");
0183: makeActionHash(); // put actions in a HashMap
0184:
0185: if (DEBUG)
0186: System.out.print(" Creating lists. ");
0187:
0188: //tablePanel.addListSelectionListener(this);
0189: tablePanel
0190: .addListSelectionListener(new ListSelectionListener() {
0191: public void valueChanged(ListSelectionEvent e) {
0192: // the next line is to prevent this from running twice
0193: if (!tablePanel.getValueIsAdjusting()) {
0194: // if user selected column heading, dontmake a fool of yourself
0195: // if (tablePanel.isSelectedIndex(0) == true) {
0196: //tablePanel.clearSelection();
0197: //return;
0198: // }
0199:
0200: Object[] selected = tablePanel
0201: .getSelectedValues();
0202: int size = selected.length;
0203: StringBuffer sTables = new StringBuffer(
0204: size);
0205: for (int i = 0; i < size; i++) {
0206: if (i > 0)
0207: sTables.append(", ");
0208: sTables.append("'"
0209: + selected[i].toString().trim()
0210: + "'");
0211: }
0212: //String SQLString = " select column_name from user_tab_columns where ";
0213: //SQLString = SQLString + " table_name in (" + sTables + ")" ;
0214: //SQLVect = myjdbc.runSQL (SQLString);
0215: //
0216: List vv = new Vector();
0217: for (int i = 0; i < size; i++) {
0218: List vx = new ArrayList();
0219: try {
0220: vx = (myjdbc
0221: .getColumnNames(selected[i]
0222: .toString().trim()));
0223: // only if more than one table selected should we
0224: // attach the table name to the column name
0225: if (size > 1)
0226: vx = ArrayUtil.prependString(
0227: vx, selected[i]
0228: .toString()
0229: .trim() + '.');
0230: vv.addAll((Collection) vx);
0231: } catch (SQLException sqle) {
0232: System.err.println("107:"
0233: + sqle.toString());
0234: sqle.printStackTrace();
0235: }
0236: // if connection null
0237: catch (NullPointerException sqle) {
0238: }
0239: }
0240: columnPanel.setListData(new Vector(vv));
0241: String sqlpattern = null;
0242: if ((sqlpattern = (String) getAttribute("fixedsql")) != null) {
0243: if (sqlpattern.indexOf("$tn") != -1) {
0244: tp.makeOutputAreaVisible();
0245: for (int i = 0; i < size; i++) {
0246: String tmpsql = PerlWrapper
0247: .perlSubstitute(
0248: "s/\\$tn/"
0249: + selected[i]
0250: .toString()
0251: + "/g",
0252: sqlpattern);
0253: if ("on"
0254: .equalsIgnoreCase((String) getAttribute(
0255: "debugging",
0256: "off")))
0257: System.out.println("tmp:"
0258: + tmpsql);
0259: //String output = myjdbc.runSQL( tmpsql );
0260: //tp.appendOutputArea('\n'+output);
0261: Run(tmpsql);
0262:
0263: } //for
0264: } // if tn
0265: } // fixedsql
0266:
0267: } // isadjusting
0268: }
0269:
0270: });
0271:
0272: // RK added on 20031226 19:30:18
0273: // Now these are automatically picked up.
0274: // However, we need to pick up keystrokes also.
0275: Map mact = getHashedActions("SQL");
0276: mact.putAll(getHashedActions("List"));
0277: Iterator it = mact.values().iterator();
0278: Action act;
0279: String name;
0280: ActionMap am = tablePanel.getActionMap();
0281: while (it.hasNext()) {
0282: act = (Action) it.next();
0283: name = (String) act.getValue(Action.NAME);
0284: am.put(name, act);
0285: }
0286: // TODO these need to picked from file
0287: InputMap im = tablePanel.getInputMap();
0288: im.put(KeyStroke.getKeyStroke("alt shift D"),
0289: SQLActions.showFilteredDataAction);
0290: im.put(KeyStroke.getKeyStroke("alt C"),
0291: ListActions.viewCountAction);
0292: im.put(KeyStroke.getKeyStroke("control D"),
0293: ListActions.viewDistinctAction);
0294: im.put(KeyStroke.getKeyStroke("control C"),
0295: ListActions.viewColumnsAction);
0296: im.put(KeyStroke.getKeyStroke("alt I"),
0297: ListActions.viewIndexesAction);
0298: im.put(KeyStroke.getKeyStroke("alt 1"), Actions.gotoInput);
0299: im.put(KeyStroke.getKeyStroke("alt 2"), Actions.gotoOutput);
0300: im.put(KeyStroke.getKeyStroke("alt D"),
0301: SQLActions.showDataAction);
0302:
0303: columnPanel
0304: .addListSelectionListener(new ListSelectionListener() {
0305: public void valueChanged(ListSelectionEvent e) {
0306: if (columnPanel.getValueIsAdjusting())
0307: return;
0308: // if user selected column heading, dontmake a fool of yourself
0309: // if (columnPanel.isSelectedIndex(0) == true) {
0310: // columnPanel.clearSelection();
0311: // return;
0312: // }
0313: /* this kept appending the same value during multiple select
0314: Object selected = columnPanel.getSelectedValue();
0315: */
0316: Object[] selected = columnPanel
0317: .getSelectedValues();
0318: int len = selected.length;
0319: if (len > 0)
0320: //tp.appendInputArea (" " + selected[ len - 1 ].toString() + ",");
0321: tp.insertInputArea(" "
0322: + selected[len - 1].toString()
0323: + ",");
0324: }
0325: });
0326:
0327: if (DEBUG)
0328: System.out.print(" Setting up scroll panes..");
0329: tableScroll = new JScrollPane(tablePanel);
0330: columnScroll = new JScrollPane(columnPanel);
0331:
0332: // added on 20011103
0333: columnScroll.setColumnHeaderView((new JLabel("Columns",
0334: SwingConstants.CENTER)));
0335: tableScroll.setColumnHeaderView((new JLabel("Tables",
0336: SwingConstants.CENTER)));
0337:
0338: //Lay out the components.
0339: Container cp = this .getContentPane();
0340: cp.setLayout(new BorderLayout());
0341: createButtonPanel();
0342:
0343: if ("south".equalsIgnoreCase((String) getAttribute(
0344: "buttonorient", "south")))
0345: cp.add(buttonPanel, BorderLayout.SOUTH);
0346: else
0347: cp.add(buttonPanel, BorderLayout.NORTH);
0348: createListPanel();
0349: jtInput = new JTextArea();
0350: jtInput.setEditable(true);
0351: //jtInput.setBackground(java.awt.Color.lightGray);
0352: jtInput.setBackground(java.awt.Color.magenta);
0353: jtInput.setDocument(sd1);
0354: jtInput.addKeyListener(new TabKeyListener(jtInput));
0355:
0356: inpPanel = new JScrollPane(jtInput);
0357: mainPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, inpPanel,
0358: tp); // aaah, much better
0359: mainPane.setOneTouchExpandable(true);
0360: mainPane.setDividerLocation(100);
0361: mainPane.setResizeWeight(1);
0362: mainPane.setPreferredSize(new Dimension(800, 500));
0363:
0364: // jtError is the box below
0365: jtError = new JTextArea("Message area. ");
0366: jtError.setEditable(false);
0367: //jtError.setBackground(java.awt.Color.lightGray);
0368: jtError.setBackground(java.awt.Color.pink);
0369: JScrollPane errPanel = new JScrollPane(jtError);
0370: fullPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, mainPane,
0371: errPanel); // aaah, much better
0372: fullPane.setOneTouchExpandable(true);
0373: fullPane.setDividerLocation(500);
0374: fullPane.setResizeWeight(0);
0375: //fullPane.setPreferredSize(new Dimension(800, 800));
0376: fullPane.setPreferredSize(new Dimension(600, 600));
0377:
0378: //gridbag.setConstraints(fullPane, c);
0379: // added on 20011128
0380: inpPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, fullPane,
0381: splitPane); // aaah, much better
0382: //gridbag.setConstraints(splitPane, c);
0383: inpPane.setOneTouchExpandable(true);
0384: inpPane.setDividerLocation(600);
0385: inpPane.setResizeWeight(0);
0386: //inpPane.setPreferredSize(new Dimension(1000, 800));
0387: inpPane.setPreferredSize(new Dimension(800, 600));
0388: //gridbag.setConstraints(inpPane, c);
0389:
0390: if ("south".equalsIgnoreCase((String) getAttribute(
0391: "buttonorient", "south")))
0392: cp.add(inpPane, BorderLayout.NORTH);
0393: else
0394: cp.add(inpPane, BorderLayout.SOUTH);
0395: // Create the buttonPanel and place it
0396: //createButtonPanel ();
0397: setJMenuBar(menubar);
0398: createMetaDataMenu();
0399:
0400: tablePanel.setEnabled(false);
0401: columnPanel.setEnabled(false);
0402:
0403: // create Properties
0404: //createProperties();
0405: setSize(1000, 800);
0406: pack();
0407: setVisible(true);
0408: } // end of init
0409:
0410: private void createButtonPanel() {
0411:
0412: // THESE BUTTONS SHOULD BE REPLACED WITH ACTIONS
0413: runButton = new JButton("Run");
0414: runButton.setActionCommand(RUN);
0415: runButton.setToolTipText("Run SQL from Input");
0416: runButton.addActionListener(this );
0417: runButton.setEnabled(false);
0418:
0419: runSelectedButton = new JButton("Run Selected");
0420: runSelectedButton.setActionCommand(RUN_SELECTED);
0421: runSelectedButton.setToolTipText("Run SQL from Selection");
0422: runSelectedButton.addActionListener(this );
0423: runSelectedButton.setEnabled(false);
0424:
0425: clearButton = new JButton("Clear");
0426: clearButton.setActionCommand(CLEAR);
0427: clearButton.setToolTipText("Clear Visible Area");
0428: clearButton.addActionListener(this );
0429:
0430: metaButton = new JButton("Meta");
0431: metaButton.setActionCommand(META);
0432: metaButton.setEnabled(false);
0433: metaButton.setToolTipText("Database Metadata");
0434: metaButton.addActionListener(this );
0435:
0436: exitButton = new JButton("Exit");
0437: exitButton.setActionCommand(EXIT);
0438: exitButton.setToolTipText("Exit Application");
0439: //constructButton.setBackground(SystemColor.control);
0440: exitButton.addActionListener(this );
0441:
0442: connectButton = new JButton("Connect");
0443: connectButton.setActionCommand(CONNECT);
0444: connectButton.setToolTipText("Connect to Database");
0445: connectButton.addActionListener(this );
0446:
0447: constructButton = new JButton("Construct");
0448: constructButton.setActionCommand(CONSTRUCT);
0449: constructButton.setToolTipText("Construct SQL from Lists");
0450: // constructButton.setBackground(SystemColor.control);
0451: constructButton.addActionListener(this );
0452: constructButton.setEnabled(false);
0453: // THESE SHOULD ALL BE ACTIONS NOT JBUTTONS TODO XXX
0454:
0455: Action a = getHashedAction("SQL", SQLActions.showDataAction);
0456: a.putValue(Action.NAME, "Data");
0457: a.putValue(Action.SHORT_DESCRIPTION, "Show all data in table");
0458: a.setEnabled(false);
0459: buttonPanel = new JToolBar();
0460: buttonPanel.setLayout(new FlowLayout());
0461: //buttonPanel.setPreferredSize(new Dimension(200, 75));
0462: //buttonPanel.setFloatable(false); // there is an illegal argument being thrown - cannot add to layout, constraint msut be gbc
0463: buttonPanel.addContainerListener(this );
0464: buttonPanel.add(runButton);
0465: buttonPanel.add(runSelectedButton);
0466: buttonPanel.add(clearButton);
0467: buttonPanel.add(constructButton);
0468: //buttonPanel.add (showDataButton);
0469: //buttonPanel.add( new SQLActions.ShowDataAction(this) );
0470: buttonPanel.add(a);
0471: buttonPanel.add(connectButton);
0472: buttonPanel.add(metaButton);
0473: buttonPanel.add(exitButton);
0474:
0475: menu = new JMenu("Actions");
0476: menu.setMnemonic('A');
0477: menubar = new JMenuBar();
0478: menubar.add(menu);
0479:
0480: //SQLActions sqla = new SQLActions(this);
0481: //JMenuItem jmi = menu.add( new SQLActions.RunAction(this) );
0482: JMenuItem jmi = menu.add(getHashedAction("SQL",
0483: SQLActions.runAction));
0484: jmi.setMnemonic('R');
0485: //jmi.setEnabled(false);
0486: jmi.setEnabled(true);
0487: jmi = menu
0488: .add(getHashedAction("SQL", SQLActions.runBatchAction));
0489: menu.add(new SQLActions.ConnectAction(this ));
0490:
0491: // RK added on 20040126 16:15:15
0492: menu.add(new SQLActions.NewConnectAction(this ));
0493:
0494: jmi = menu.add(new SQLActions.SaveOutputAction(this ));
0495: jmi.setMnemonic('O');
0496: jmi = menu.add(new SQLActions.SaveHistoryAction(this ));
0497: jmi.setMnemonic('H');
0498: jmi = menu.add(new SQLActions.SaveTableAction(this ));
0499: jmi.setMnemonic('T');
0500: //menu.add( new TableActions.DeleteAction(this) );
0501: // XXX i should not have to create a action for this when
0502: // i have a command. i should be able to use the command here.
0503: jmi = menu.add(new SQLActions.HelpAction(this ));
0504: jmi = menu.add(new SQLActions.SettingsAction(this ));
0505:
0506: jmi = menu
0507: .add(getHashedAction("SQL", SQLActions.showDataAction));
0508: jmi.setMnemonic('D');
0509: jmi = menu.add(new SQLActions.ExitAction(this ));
0510: jmi.setMnemonic('X');
0511: }
0512:
0513: private void createListPanel() {
0514:
0515: splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
0516: tableScroll, columnScroll);
0517: splitPane.setOneTouchExpandable(true);
0518: splitPane.setDividerLocation(200);
0519: splitPane.setContinuousLayout(true);
0520: splitPane.setPreferredSize(new Dimension(100, 200));
0521:
0522: }
0523:
0524: protected void createMetaDataMenu() {
0525:
0526: if (DEBUG)
0527: System.out.print(" create meta menu ");
0528: menuMetaData = new JMenu("MetaData");
0529: menuMetaData.setMnemonic('M');
0530: menuMetaData.setEnabled(false);
0531: menubar.add(menuMetaData);
0532: Collection coll = ((Map) htActions.get("DB")).values();
0533: Iterator it = coll.iterator();
0534: JMenuItem jmi;
0535: while (it.hasNext()) {
0536: jmi = menuMetaData.add((Action) it.next());
0537: // this depends on text starting with "view-" - i m using
0538: // 5th character
0539: //jmi.setMnemonic((new Character(jmi.getText().charAt(5)).toUpperCase()).charValue());
0540: jmi.setMnemonic(jmi.getText().toUpperCase().charAt(5));
0541: }
0542:
0543: menuTableData = new JMenu("Table");
0544: menuTableData.setMnemonic('T');
0545: menuTableData.setEnabled(false);
0546: menubar.add(menuTableData);
0547: coll = ((Map) htActions.get("Table")).values();
0548: it = coll.iterator();
0549: Action act;
0550: while (it.hasNext()) {
0551: act = (Action) it.next();
0552: jmi = menuTableData.add(act);
0553: String acc = (String) act.getValue("accelerator");
0554: if (acc != null)
0555: jmi.setAccelerator(KeyStroke.getKeyStroke(acc));
0556: //jmi.setMnemonic((new Character(jmi.getText().charAt(0)).toUpperCase()).charValue());
0557: jmi.setMnemonic(jmi.getText().toUpperCase().charAt(0));
0558: }
0559: menuFrameData = new JMenu("Frame");
0560: menuFrameData.setMnemonic('F');
0561: menuFrameData.setEnabled(false);
0562: coll = ((Map) htActions.get("Frame")).values();
0563: it = coll.iterator();
0564: while (it.hasNext()) {
0565: act = (Action) it.next();
0566: jmi = menuFrameData.add(act);
0567: String acc = (String) act.getValue("accelerator");
0568: if (acc != null)
0569: jmi.setAccelerator(KeyStroke.getKeyStroke(acc));
0570: }
0571: menubar.add(menuFrameData);
0572:
0573: menuListData = new JMenu("List");
0574: menuListData.setMnemonic('L');
0575: menuListData.setEnabled(false);
0576: coll = ((Map) htActions.get("List")).values();
0577: it = coll.iterator();
0578: while (it.hasNext()) {
0579: act = (Action) it.next();
0580: jmi = menuListData.add(act);
0581: String acc = (String) act.getValue("accelerator");
0582: if (acc != null)
0583: jmi.setAccelerator(KeyStroke.getKeyStroke(acc));
0584: }
0585: menubar.add(menuListData);
0586:
0587: if (DEBUG)
0588: System.out.print(" finished create meta menu ");
0589: }
0590:
0591: /** make the connector menu - this only happens after reading ini.
0592: * Actually this only happens after connecting, which is silly ?
0593: * If i dont connect on startup then i dont see this.
0594: */
0595: protected void makeConnectorMenu() {
0596:
0597: String t;
0598: if ((t = (String) getAttribute("connectors")) == null)
0599: return;
0600: String[] connectors = ArrayUtil.split(t, ',');
0601:
0602: // RK added on 20040126 17:44:12
0603: // so that not create again and again with each connection
0604: // TOTEST
0605: if (menuConnection != null)
0606: menubar.remove(menuConnection);
0607:
0608: menuConnection = new JMenu("Connections");
0609: final SQLForm form = this ;
0610: Action a;
0611: for (int i = 0; i < connectors.length; i++) {
0612: final String key = connectors[i];
0613: String line = (String) getAttribute(key);
0614: if (line == null) {
0615: System.err
0616: .println("Warning: Didn't find the definition for connector:["
0617: + key + "]");
0618: continue;
0619: }
0620: line = line.trim().substring(1, line.length() - 1);
0621:
0622: final String[] connparams = ArrayUtil.split(line, ',');
0623:
0624: a = new AbstractAction() {
0625: public boolean isEnabled() {
0626: return true;
0627: }
0628:
0629: public void actionPerformed(ActionEvent e) {
0630: // first close connection
0631: try {
0632: // 0 = DSN, 2=UID, 3=PWD, this, 1=driver);
0633: // if password not saved, then prompt
0634: if (connparams[3] == null
0635: || connparams[3].trim().equals("")
0636: || connparams[3].equals("?")) {
0637: // TODO should use a password field
0638: connparams[3] = form
0639: .getInput("Enter password for:"
0640: + connparams[0]);
0641: }
0642: myjdbc = new SQLJDBC(connparams[0],
0643: connparams[2], connparams[3], form,
0644: connparams[1]);
0645: } catch (Exception exc) {
0646: System.err.println("498:EXC:" + exc.toString());
0647: }
0648: }
0649: };
0650: a.putValue(Action.LONG_DESCRIPTION, connparams[0]
0651: + connparams[2]);
0652: a.putValue(Action.NAME, key);
0653: menuConnection.add(a);
0654: menubar.add(menuConnection);
0655: }
0656: }
0657:
0658: /** Make the menu of bookmarks.
0659: * the diff conditions here need to be checked out...
0660: */
0661: public void makeBookmarkMenu() {
0662:
0663: // this should be destroyed when reconnecting...
0664: if (htBookmarks == null || htBookmarks.size() == 0) {
0665: if (menuBookmark != null) {
0666: System.err.println("SQLForm 419:not tested earlier...");
0667: System.err.println("isexisting?:"
0668: + menubar.getComponentIndex(menuBookmark));
0669: menubar.remove(menuBookmark);
0670: menubar.invalidate();
0671: menubar.validate();
0672: menubar.repaint();
0673: }
0674: //return; XXX
0675: } else {
0676: if (menuBookmark != null)
0677: menubar.remove(menuBookmark);
0678: menuBookmark = null; // are the previous actions also disposed ??
0679: menuBookmark = new JMenu("Bookmarks");
0680: menuBookmark.setMnemonic('B');
0681: Iterator e = htBookmarks.keySet().iterator();
0682: Action a;
0683: final SQLForm _form = this ;
0684: while (e.hasNext()) {
0685: final String key = (String) e.next();
0686: a = new AbstractAction() {
0687: public boolean isEnabled() {
0688: return true;
0689: }
0690:
0691: public void actionPerformed(ActionEvent e) {
0692: //tp.appendInputArea(this.LONG_DESCRIPTION);
0693: //tp.appendInputArea((String)htBookmarks.get(key));
0694: String value = (String) htBookmarks.get(key);
0695: if (value.indexOf('$') > -1)
0696: value = TableActions.substituteFields(
0697: value, _form, 4);
0698: tp.appendInputArea(value);
0699: }
0700: };
0701: a.putValue(Action.LONG_DESCRIPTION, htBookmarks
0702: .get(key));
0703: a.putValue(Action.NAME, key);
0704: menuBookmark.add(a);
0705: }
0706: } // there were some static bookmarks
0707: // now we check for dynamic bookmarks
0708: String sbookmarks = (String) getAttribute("bookmarks");
0709: if (sbookmarks != null) {
0710: if (menuBookmark == null)
0711: menuBookmark = new JMenu("Bookmarks");
0712: menuBookmark.addSeparator();
0713: String[] abookmarks = ArrayUtil.split(sbookmarks, ',');
0714: Action a;
0715: for (int i = 0; i < abookmarks.length; i++) {
0716: final String key = abookmarks[i];
0717: a = new AbstractAction() {
0718: public boolean isEnabled() {
0719: return true;
0720: }
0721:
0722: public void actionPerformed(ActionEvent e) {
0723: bookmarkLoad(key);
0724: }
0725: };
0726: //a.putValue(Action.LONG_DESCRIPTION, value);
0727: a.putValue(Action.NAME, "load " + key);
0728: menuBookmark.add(a);
0729: } // for
0730: } // sbookmark != null
0731: menubar.add(menuBookmark);
0732: menubar.invalidate();
0733: menubar.validate();
0734: menubar.repaint();
0735: }
0736:
0737: public void componentAdded(ContainerEvent e) {
0738: //displayMessage(" added to ", e);
0739: }
0740:
0741: public void componentRemoved(ContainerEvent e) {
0742: //displayMessage(" removed from ", e);
0743: }
0744:
0745: /*
0746: * This could have been implemented as two or three
0747: * classes or objects, for clarity.
0748: */
0749: public void actionPerformed(ActionEvent e) {
0750: String command = e.getActionCommand();
0751:
0752: if (command == RUN) {
0753: // This will submit the SQL to the Server and put output in
0754: // output area
0755:
0756: runAction();
0757: } else if (command == RUN_SELECTED) {
0758: // This will submit the selected line as SQL to the Server
0759: // and put output in output area
0760: runSelectedAction();
0761: } else if (command == EXIT) {
0762: exitAction();
0763: } else if (command == CLEAR) {
0764: clearAction();
0765: } else if (command == META) {
0766: metaAction();
0767: } else if (command == CONNECT) {
0768: connectAction();
0769: } else if (command == SHOWDATA) {
0770: new SQLActions.ShowDataAction(this );
0771: } else if (command == CONSTRUCT) {
0772: // construct an SQL based on selections in lists
0773: constructAction();
0774: }
0775: }
0776:
0777: /** Passes the content of input box to the Run method.
0778: */
0779: public void runAction() {
0780: // This will submit the SQL to the Server and put output in
0781: // output area
0782:
0783: //if (jtInput.hasFocus())
0784: String s = jtInput.getText();
0785: if (s != null && s.trim().length() > 0)
0786: Run(s);
0787: else
0788: Run(tp.getSQL());
0789: }
0790:
0791: /** This will submit the selected line as SQL to the Server
0792: and put output in output area
0793: */
0794: public void runSelectedAction() {
0795: try {
0796: //if (jtInput.hasFocus())
0797: String s = jtInput.getSelectedText();
0798: if (s != null && s.trim().length() > 0)
0799: //Run (jtInput.getSelectedText());
0800: Run(s);
0801: else
0802: Run(tp.getSelection());
0803: } catch (NullPointerException ex) {
0804: JOptionPane.showMessageDialog(this ,
0805: "Error in query or nothing selected!");
0806: }
0807: }
0808:
0809: /** Action when exit pressed.
0810: */
0811: public void exitAction() {
0812: try {
0813: myjdbc.closeConnection();
0814: } catch (Exception exc) {
0815: }
0816: System.out.println("Bye. press enter..");
0817: System.exit(0);
0818: }
0819:
0820: /** action when clear button pressed.
0821: */
0822: public void clearAction() {
0823: if (jtInput.hasFocus()) // not working cant clear
0824: jtInput.setText("");
0825: else {
0826: int ind = tp.getTabbedPane().getSelectedIndex();
0827: switch (ind) {
0828: case 0:
0829: tp.clearInputArea();
0830: break;
0831: case 1:
0832: tp.clearOutputArea();
0833: break;
0834: //case 2: tp.clearErrorArea(); break;
0835: case 3:
0836: tp.scrapArea.setText("");
0837: break;
0838: case 4:
0839: tp
0840: .updateTable(new javax.swing.table.DefaultTableModel());
0841: break;
0842: } // switch
0843: } // else
0844: }
0845:
0846: /** when Meta button pressed. */
0847: public void metaAction() {
0848:
0849: // This will display metadata for selected or all tables
0850: Object[] selected = tablePanel.getSelectedValues();
0851: int size = selected.length;
0852: StringBuffer sb = new StringBuffer(128);
0853: if (size == 0) {
0854: sb.append("Catalogs: \n");
0855: sb.append(IsqlUtil.printVector(myjdbc.SQLGetCatalogs()));
0856: sb.append("Schemas: \n");
0857: sb.append(IsqlUtil.printVector(myjdbc.SQLGetSchemas()));
0858: sb.append("Tables: \n");
0859: sb.append(IsqlUtil.printVector(myjdbc.SQLGetTables(), 5));
0860: } else {
0861: String lastTable = selected[size - 1].toString().trim();
0862: List mVect = myjdbc.SQLGetColumns(lastTable);
0863: //ArrayList mVect = myjdbc.getColumnNames(lastTable);
0864: sb.append(lastTable + " Columns: \n");
0865: sb.append(IsqlUtil.printVector(mVect, 18));
0866: sb.append(lastTable + " Primary Keys: \n");
0867: sb.append(IsqlUtil.printVector(myjdbc
0868: .SQLGetPrimaryKeys(lastTable), 6));
0869: sb.append(lastTable + " Index Info: \n");
0870: sb.append(IsqlUtil.printVector(myjdbc
0871: .SQLGetIndexInfo(lastTable), 13));
0872: sb.append(lastTable + " Imported Keys: \n");
0873: sb.append(IsqlUtil.printVector(myjdbc
0874: .SQLGetImportedKeys(lastTable), 14));
0875: sb.append(lastTable + " Exported Keys: \n");
0876: sb.append(IsqlUtil.printVector(myjdbc
0877: .SQLGetExportedKeys(lastTable), 14));
0878: }
0879: sb.append("\nGive command reflect DatabaseMetaData\n");
0880: tp.appendOutputArea(sb.toString());
0881: tp.makeOutputAreaVisible();
0882: }
0883:
0884: public void readParams() {
0885: //String inifile;
0886: if (args.length == 0)
0887: inifile = "mysql.ini";
0888: else
0889: inifile = args[0];
0890: TNS = new ReadTNS(inifile);
0891: TNS.parseFile();
0892: htParams = TNS.getParams();
0893: htBookmarks = TNS.getBookmarks();
0894: htLinks = TNS.getLinks();
0895:
0896: System.out.println(" before master processing ... ");
0897: htMaster = new HashMap();
0898: ArrayList al = new ArrayList(htLinks.values());
0899: for (int i = 0; i < al.size(); i++) {
0900: String item = (String) al.get(i);
0901: String p[] = ArrayUtil.split(item, ':');
0902: addToMaster(p[1], item);
0903: }
0904: htSorts = TNS.getSorts();
0905: htFilters = TNS.getFilters();
0906: bindings = TNS.getBindings();
0907: // unfortunately this is tied to connect button and should
0908: // happen on startup
0909: //tp.setAbbreviationTable(TNS.getAbbreviations());
0910: //sd1.setAbbreviationTable(TNS.getAbbreviations());
0911: // this needs to tested with the case that one of the params
0912: // is not there in ini file
0913: // NOW We need to pick these out of default_connector
0914: String def_conn;
0915: if ((def_conn = (String) getAttribute("default_connector")) == null) {
0916: System.err
0917: .println("You dont have a default_connector in your init file. Hope you have set DSN, UID, DRIVER and PWD");
0918: //System.err.println( "Please use new-connection to connect.");
0919:
0920: //return;
0921: } else {
0922: System.out.println("default connector:" + def_conn);
0923: String line = (String) getAttribute(def_conn);
0924: line = line.trim().substring(1, line.length() - 1);
0925: if (SQLForm.DEBUG)
0926: System.out.println("Connect string:" + line);
0927: String[] connparams = ArrayUtil.split(line, ',');
0928: setAttribute("DSN", connparams[0]);
0929: setAttribute("DRIVER", connparams[1]);
0930: setAttribute("UID", connparams[2]);
0931: setAttribute("PWD", connparams[3]);
0932: if (SQLForm.DEBUG) {
0933: System.out.println("Using:" + connparams[0] + ","
0934: + connparams[1]);
0935: System.out.println("Using:" + connparams[2] + ","
0936: + connparams[3]);
0937: }
0938: }
0939:
0940: if (htParams.get("DSN") == null || htParams.get("UID") == null
0941: || htParams.get("PWD") == null) {
0942: // System.err.println ( "INI file should have default_connector or DSN, UID and PWD entries");
0943: //JOptionPane.showMessageDialog(this, "INI file should have DSN, UID and PWD entries. Use Action->new-connection to connect");
0944: return;
0945: }
0946: }
0947:
0948: // Connect to the database and fill table column
0949: // THREADED setCursor (WAIT_CURSOR);
0950: // we are now passing this so that thread can update buttons and list
0951: public void connectAction() {
0952: // i feel connect should always open the Connect box
0953: if (htParams.get("DSN") == null || htParams.get("UID") == null
0954: || htParams.get("PWD") == null
0955: || htParams.get("DRIVER") == null) {
0956: Action tmp = new SQLActions.NewConnectAction(this );
0957: tmp.actionPerformed(null);
0958: return;
0959: }
0960: try {
0961: myjdbc = new SQLJDBC(htParams.get("DSN").toString(),
0962: htParams.get("UID").toString(), htParams.get("PWD")
0963: .toString(), this , htParams.get("DRIVER")
0964: .toString());
0965: } catch (SQLException ex) {
0966: System.err.println("SQLEXCEPTION" + ex.toString());
0967: new SQLExceptionPrint(ex);
0968: } catch (ClassNotFoundException ex) {
0969: System.err.println("ClassNotFoundException:"
0970: + ex.toString());
0971: new SQLExceptionPrint(ex);
0972: }
0973: // THREADED runButton.setEnabled (true);
0974: // THREADED runSelectedButton.setEnabled (true);
0975: // THREADED constructButton.setEnabled (true);
0976: // THREADED fillTableList();
0977: // THREADED setCursor (DEFAULT_CURSOR);
0978: }
0979:
0980: /** connect giving a driver, url, username and password.
0981: */
0982: public void connect(String driver, String DSN, String UID,
0983: String PWD) throws SQLException, ClassNotFoundException {
0984:
0985: myjdbc = new SQLJDBC(DSN, UID, PWD, this , driver);
0986:
0987: }
0988:
0989: public void constructAction() {
0990: // construct an SQL based on selections in lists
0991: if ("on"
0992: .equalsIgnoreCase((String) getAttribute("constructclears")))
0993: tp.clearInputArea();
0994: tp.makeInputAreaVisible();
0995: tp.appendInputArea(constructSQL());
0996: }
0997:
0998: /** fillTableList ()
0999: * This fills the tablePanel with tablenames for that user
1000: */
1001: public void fillTableList() {
1002: List v = new ArrayList(20);
1003: try {
1004: v = myjdbc.getTableNames();
1005: System.out.println(" fillTableList:" + v.size()); // XXX
1006: tablePanel.setListData(new Vector(v));
1007:
1008: } catch (SQLException sqle) {
1009: System.err.println("407:" + sqle.toString());
1010: }
1011: }
1012:
1013: /** puts all table names and column names in the tabbable completion
1014: * );cache. This is passed to SQLTabbedPane and from there to
1015: * SmartDocument,
1016: */
1017: public void setTabTable() {
1018:
1019: ArrayList v = getAllTablePanelValues();
1020: ArrayList v1 = getColumnList();
1021: if (v1 != null)
1022: v.addAll(v1);
1023: String tabs[] = new String[v.size()];
1024: tp.setTabTable((String[]) v.toArray(tabs));
1025: sd1.setTabTable((String[]) v.toArray(tabs));
1026: }
1027:
1028: /** returns a list of tablepanel values, in other words a list
1029: * of tables.
1030: */
1031: public ArrayList getAllTablePanelValues() {
1032: ListModel lm = tablePanel.getModel();
1033: int len = lm.getSize();
1034: ArrayList v = new ArrayList(len);
1035: for (int i = 0; i < len; i++) {
1036: v.add((String) lm.getElementAt(i));
1037: }
1038: return v;
1039: }
1040:
1041: /** parses list of tables to be cached from ini file and
1042: * returns column names of those tables.
1043: */
1044: public ArrayList getColumnList() {
1045:
1046: String scache = null;
1047: if ((scache = (String) htParams.get("columncaching")) != null) {
1048: return getColumnList(scache);
1049: }
1050: return null;
1051: }
1052:
1053: /** returns columnlist based on given cache which could be user
1054: * input at runtime
1055: */
1056: public ArrayList getColumnList(String scache) {
1057:
1058: try {
1059: String cachelist[] = ArrayUtil.split(scache, ',');
1060: ArrayList v = new ArrayList(cachelist.length * 10);
1061: if ("on".equalsIgnoreCase((String) getAttribute(
1062: "debugging", "off")))
1063: System.out.println("Caching ...");
1064: for (int i = 0; i < cachelist.length; i++) {
1065: if ("on".equalsIgnoreCase((String) getAttribute(
1066: "debugging", "off")))
1067: System.out.print(cachelist[i] + " ");
1068: // check for wildcard in file name
1069: // Note that underscores in file name trigger
1070: // expansion.
1071: if (cachelist[i].indexOf('%') > -1
1072: || cachelist[i].indexOf('_') > -1) {
1073: List tv = myjdbc.getTableNames(cachelist[i]);
1074: Iterator it = tv.iterator();
1075: while (it.hasNext()) {
1076: v.addAll(myjdbc.getColumnNames((String) it
1077: .next()));
1078: }
1079: } // if wildcard
1080: else
1081: v.addAll(myjdbc.getColumnNames(cachelist[i]));
1082: } // for
1083: if ("on".equalsIgnoreCase((String) getAttribute(
1084: "debugging", "off")))
1085: System.out.println(".");
1086: return v;
1087: } catch (SQLException exc) {
1088: System.err.println("Caching tables/columns: 530:"
1089: + exc.toString());
1090: exc.printStackTrace();
1091: }
1092: return null;
1093: }
1094:
1095: /** construct an sql based on selected tables and columns and
1096: * place in input area.
1097: * TODO- Needs to be factored out.
1098: */
1099: public String constructSQL() {
1100: Object[] selectedTables = tablePanel.getSelectedValues();
1101: int cntTables = selectedTables.length;
1102: //if (cntTables == 0 && cntColumns == 0)
1103: if (cntTables == 0)
1104: return "";
1105: Object[] selectedColumns = columnPanel.getSelectedValues();
1106: int cntColumns = selectedColumns.length;
1107: // search for each column in htLinks - is there a faster way
1108: String strColumns, strTables;
1109: String sDelim = ",\n\t";
1110: String newSQL, wherestring = "";
1111: strTables = getDelimString(selectedTables, sDelim);
1112: if (cntColumns == 0)
1113: strColumns = " * ";
1114: else {
1115: // check if any fields need adding through links
1116: ArrayList al = new ArrayList(cntColumns);
1117: for (int i = 0; i < selectedColumns.length; i++) {
1118: // get both columnname and table plus columnname
1119: String fullname = selectedColumns[i].toString();
1120: String colname = null;
1121: // if no dot in fullname (single table selected)
1122: if (!(fullname.indexOf('.') > -1)) {
1123: colname = fullname;
1124: fullname = selectedTables[0].toString() + '.'
1125: + colname;
1126: } else {
1127: // retrieve column from fullname
1128: colname = fullname
1129: .substring(fullname.indexOf('.') + 1);
1130: }
1131: // first look for fullname rule, else colname rule
1132: // if there are no links then add name and continue
1133: String link = getLink(fullname);
1134: if (link == null)
1135: link = getLink(colname);
1136: if (link == null) {
1137: //al.add( selectedColumns[i].toString() + " /* 1 */" );
1138: // made it full since there were ambiguities
1139: al.add(fullname + " /* full 1 */");
1140: continue;
1141: }
1142: // there was a link
1143: // so now start linking to other tables
1144: String[] alink = ArrayUtil.split(link, ':');
1145: // 0 is link table (other)
1146: // 1 is key in that table
1147: // 2 is the desc field in that table
1148: // 3 is possible where condition
1149:
1150: // if other table already in select then dont attempt
1151: if (Arrays.binarySearch(selectedTables, alink[0]) > -1) {
1152: //al.add( selectedColumns[i].toString() );
1153: //RK added on 20031231 18:25:31
1154: //trying to get rid of ambiguity
1155: al.add(fullname + "/* FULL */ ");
1156: continue;
1157: }
1158: //add to column list
1159: al.add(fullname + "/* 2 */"); // resolution required
1160: al.add(alink[0] + '.' + alink[2]); // add desc field
1161: strTables += ',' + alink[0]; // add other table to table list
1162: if (wherestring.trim().length() > 0)
1163: wherestring += " and ";
1164: wherestring += ' ' + fullname + " = " + alink[0] + '.'
1165: + alink[1];
1166: // add possible where condition
1167: if (alink.length == 4)
1168: wherestring += " and " + alink[3];
1169: } // for
1170: selectedColumns = new Object[al.size()];
1171: al.toArray(selectedColumns);
1172:
1173: strColumns = getDelimString(selectedColumns, sDelim);
1174: } //else
1175:
1176: newSQL = "\nSELECT\n\t" + strColumns + "\n" + "FROM\n\t"
1177: + strTables + " ";
1178: if (cntTables > 1) {
1179: if (wherestring.trim().length() > 0)
1180: wherestring = " and " + wherestring;
1181: newSQL = newSQL + "\nWHERE ";
1182: newSQL += getPossibleJoins(selectedTables) + wherestring;
1183: // at present only first tables order by
1184: // we havent put the tablename as yet
1185: for (int i = 0; i < selectedTables.length; i++) {
1186: String filter;
1187: if ((filter = getFilter((String) selectedTables[i])) != null) {
1188: filter = formatFilter(filter,
1189: (String) selectedTables[i], columnPanel
1190: .getModel());
1191: newSQL += " and " + filter;
1192: }
1193: }
1194: String orderby = getSort(selectedTables[0].toString());
1195: if (orderby != null)
1196: newSQL += " ORDER BY " + orderby;
1197: } else {
1198: if (wherestring.trim().length() > 0) {
1199: newSQL += "\nWHERE " + wherestring;
1200: String filter;
1201: if ((filter = getFilter((String) selectedTables[0])) != null)
1202: newSQL += " and " + filter;
1203: } else {
1204: String filter;
1205: if ((filter = getFilter((String) selectedTables[0])) != null)
1206: newSQL += " WHERE " + filter;
1207: }
1208: String orderby = getSort(selectedTables[0].toString());
1209: if (orderby != null)
1210: newSQL += " ORDER BY " + orderby;
1211: }
1212: return newSQL;
1213:
1214: }
1215:
1216: /** adds tablename to the field present in the filter.
1217: */
1218: private String formatFilter(String filter, String table,
1219: ListModel lm) {
1220:
1221: String[] parts = Util.split(filter, ' ');
1222: for (int i = 0; i < parts.length; i++) {
1223: String upperpart = parts[i].toUpperCase();
1224: for (int j = 0; j < lm.getSize(); j++) {
1225: if (lm.getElementAt(j).equals(table + "." + upperpart)) {
1226: filter = Util.replace(parts[i], table + "."
1227: + upperpart, filter);
1228: }
1229: }
1230: }
1231: return filter;
1232: }
1233:
1234: /** joins an array with the delimiter.
1235: * Needs to be moved to a util class. and called join, use
1236: * stringbuffer.
1237: */
1238: protected static String getDelimString(Object[] marray, String delim) {
1239:
1240: int len = marray.length;
1241: String sDelimited = new String();
1242: for (int i = 0; i < len; i++) {
1243: if (i > 0)
1244: sDelimited = sDelimited + delim;
1245: sDelimited = sDelimited + marray[i].toString();
1246: }
1247: return sDelimited;
1248: }
1249:
1250: /** tries to make joins based on fields being identical across
1251: * tables
1252: */
1253: private String getPossibleJoins(Object[] selectedTables) {
1254:
1255: int len = selectedTables.length;
1256: String str = "";
1257: ArrayList v = new ArrayList(len);
1258: try {
1259: for (int i = 0; i < len; i++) {
1260: v
1261: .add(myjdbc
1262: .getColumnNames((String) selectedTables[i]));
1263: }
1264: for (int i = 0; i < len; i++) {
1265: ArrayList first = (ArrayList) v.get(i);
1266: for (int j = i + 1; j < len; j++) {
1267: ArrayList second = (ArrayList) v.get(j);
1268: for (int k = 0; k < first.size(); k++)
1269: if (second.contains(first.get(k))) {
1270: if (!str.equals(""))
1271: str += " and ";
1272: str += (String) selectedTables[i] + '.'
1273: + first.get(k) + " = "
1274: + (String) selectedTables[j] + '.'
1275: + first.get(k) + " \n";
1276: }
1277: }
1278: }
1279: } catch (SQLException sqle) {
1280: System.err.println("472:" + sqle.toString());
1281: }
1282: return str;
1283: }
1284:
1285: /** called from UI to execute any user command in input box.
1286: * This checks whether it is an SQL or some parameter setting.
1287: * Use this for processing all user or programmed commands.
1288: * RK added on 20040201 12:24:10 - modifed to public after moving
1289: * commands out. REFACTORED.
1290: * */
1291: public void Run(String SQLString) {
1292:
1293: if (SQLString == null || SQLString.trim().equals("")) {
1294: JOptionPane
1295: .showMessageDialog(this ,
1296: "Run where ? Enter a command or SQL statement in the input area.");
1297: return;
1298: }
1299: if (myjdbc == null) {
1300: popup("Can't run without a connection. Pls connect using connect or new-connection.");
1301: return;
1302: }
1303: int spos = SQLString.indexOf(' ');
1304: String fword = null;
1305: if (spos == -1)
1306: fword = SQLString;
1307: else
1308: fword = SQLString.substring(0, spos);
1309:
1310: if (SQLString.charAt(0) == '@')
1311: fword = "@";
1312:
1313: // RK added on 20040201 15:17:11
1314: // moved all command handling to command handler
1315: if (_commandHandler == null) {
1316: System.err
1317: .println("NEED TO INITIALIZE COMMANDHANDLER FIRST");
1318: }
1319: _commandHandler.execute(fword, SQLString);
1320:
1321: super .setCursor(java.awt.Cursor.DEFAULT_CURSOR);
1322: }
1323:
1324: /** appends the given text to the status area below. caller should
1325: * pass a newline at beginning of statement if he wishes.
1326: */
1327: public void setErrorArea(String serror) {
1328: jtError.setEditable(true);
1329: jtError.append(serror);
1330: jtError.setEditable(false);
1331: // an attempt to ensure that the last line is visible
1332: java.awt.Rectangle rBounds = jtError.getBounds(null);
1333: //java.awt.Rectangle rVis = jtError.getVisibleRect();
1334: double xb = rBounds.getHeight();
1335: //double xv = rVis.getHeight();
1336: //System.out.println("BOUNDS:"+rBounds);
1337: //System.out.println("VIS:"+ rVis);
1338: //if (rVis.getY() != (xb-xv)){
1339: //rVis.y = ((new Double)(xb-xv)).intValue();
1340: //rVis.y = (int)xb-(int)xv;
1341: //rVis.y = (int)xb;
1342: rBounds.y = (int) xb;
1343: //System.out.println("new:"+ (xb-xv));
1344: jtError.scrollRectToVisible(rBounds);
1345: //}
1346: }
1347:
1348: /** what is to be done after connection is made.
1349: */
1350: public void doAfterConnection() {
1351: runButton.setEnabled(true);
1352: runSelectedButton.setEnabled(true);
1353: constructButton.setEnabled(true);
1354: menuListData.setEnabled(true);
1355: menuTableData.setEnabled(true);
1356: menuMetaData.setEnabled(true);
1357: metaButton.setEnabled(true);
1358: Action a = getHashedAction("SQL", SQLActions.showDataAction);
1359: makeConnectorMenu(); // will create duplicates
1360: makeBookmarkMenu();
1361: a.setEnabled(true);
1362: a = getHashedAction("SQL", SQLActions.runAction);
1363: a.setEnabled(true);
1364: tablePanel.setEnabled(true);
1365: columnPanel.setEnabled(true);
1366: menuFrameData.setEnabled(true);
1367: fillTableList();
1368: setTabTable();
1369: }
1370:
1371: /** returns parameters taken from the ini file, and stored in a
1372: * Map. Could return a null, if value not found, misspelled or
1373: * file not read in as yet.
1374: */
1375: public String getAttribute(String param) {
1376: if (htParams == null)
1377: return null; // prevent NPEs if not connected.
1378: return (String) htParams.get(param);
1379: }
1380:
1381: /** user may set parameters too
1382: */
1383: public void setAttribute(String param, String value) {
1384: if (htParams == null) {
1385: setErrorArea("Please connect!");
1386: popup("Please connect!");
1387: }
1388: htParams.put(param, value);
1389: }
1390:
1391: public String getAttribute(String param, String defaultval) {
1392: String obj = (String) htParams.get(param);
1393: if (obj == null)
1394: return defaultval;
1395: return obj;
1396: }
1397:
1398: /** get link settings */
1399: public String getLink(String key) {
1400: if (DEBUG)
1401: System.out.println(" Recvd key:" + key);
1402: //if (htLinks==null) return null; // prevent NPEs if none defined
1403: if (htLinks == null) {
1404: if (htMaster == null)
1405: return null;
1406: String field;
1407: if (key.indexOf('.') > -1) {
1408: String p[] = ArrayUtil.split(key, '.');
1409: field = p[1];
1410: } else
1411: field = key;
1412: String possiblelink = (String) htMaster.get(field);
1413: return possiblelink;
1414: }
1415: String link = (String) htLinks.get(key);
1416: if (link == null) {
1417: if (htMaster == null)
1418: return null;
1419: String field;
1420: if (key.indexOf('.') > -1) {
1421: String p[] = ArrayUtil.split(key, '.');
1422: field = p[1];
1423: } else
1424: field = key;
1425: String possiblelink = (String) htMaster.get(field);
1426: if (DEBUG)
1427: System.out.println(" Got a possible link:"
1428: + possiblelink);
1429: return possiblelink;
1430: }
1431: return link;
1432: }
1433:
1434: /** get sort settings */
1435: public String getSort(String key) {
1436: if (htSorts == null)
1437: return null; // prevent NPEs if none defined
1438: return (String) htSorts.get(key);
1439: }
1440:
1441: /** get filter settings */
1442: public String getFilter(String table) {
1443: if (htFilters == null)
1444: return null; // prevent NPEs if none defined
1445: return (String) htFilters.get(table);
1446: }
1447:
1448: /** popup a given message */
1449: public void popup(String message) {
1450: JOptionPane.showMessageDialog(this , message);
1451: }
1452:
1453: /** prompt user for a message, take input and return input.
1454: */
1455: public String getInput(String message) {
1456: return JOptionPane.showInputDialog(message);
1457: }
1458:
1459: /** prompt user for a message, display choices, take input and return input.
1460: */
1461: public Object getInput(String message, String prompt,
1462: Object[] possibleValues, Object defaultvalue) {
1463: Object selectedValue = JOptionPane.showInputDialog(null,
1464: message, prompt, JOptionPane.INFORMATION_MESSAGE, null,
1465: possibleValues, defaultvalue);
1466: return selectedValue;
1467: }
1468:
1469: public String getInputCombo(String label, String title,
1470: String[] values, String defaultval) {
1471: JLabel llabel = new JLabel(label, JLabel.LEFT);
1472: JComboBox cvalues = new JComboBox(values);
1473: cvalues.setEditable(true);
1474: JPanel p = new JPanel();
1475: p.setLayout(new GridLayout(2, 2, 2, 5)); // rows, cols, hgap, vgap
1476: p.add(llabel);
1477: p.add(cvalues);
1478:
1479: int i = JOptionPane.showOptionDialog(null, p, "Enter value",
1480: JOptionPane.OK_CANCEL_OPTION,
1481: JOptionPane.PLAIN_MESSAGE, null, null, null);
1482: if (i == JOptionPane.CANCEL_OPTION)
1483: return null;
1484: return (String) cvalues.getSelectedItem();
1485: }
1486:
1487: /** stores the actions in a Map for future reference ie
1488: * enabling and disabling.
1489: */
1490: public void makeActionHash() {
1491: if (DEBUG)
1492: System.out.print(" starting action hash ");
1493: // put the SQL actions in a hash and place that in global hash
1494: Action[] a = new SQLActions(this ).getActions();
1495: Map ht = new LinkedHashMap(a.length);
1496: for (int i = 0; i < a.length; i++) {
1497: String name = (String) a[i].getValue(Action.NAME);
1498: ht.put(name, a[i]);
1499: }
1500: htActions.put("SQL", ht);
1501:
1502: // put the DB actions in a hash and place that in global hash
1503: a = new DBActions(this ).getActions();
1504: ht = new LinkedHashMap(a.length);
1505: for (int i = 0; i < a.length; i++) {
1506: String name = (String) a[i].getValue(Action.NAME);
1507: ht.put(name, a[i]);
1508: }
1509: htActions.put("DB", ht);
1510: //
1511: // put the Table actions in a hash and place that in global hash
1512: JTable jt = (JTable) this .tp.getActualComponent(4);
1513: a = new TableActions(this ).getActions(jt); // 4 for table tab
1514: ht = new LinkedHashMap(a.length); // changed to linked RK added on 20040103 23:02:39
1515: for (int i = 0; i < a.length; i++) {
1516: String name = (String) a[i].getValue(Action.NAME);
1517: ht.put(name, a[i]);
1518: }
1519: htActions.put("Table", ht);
1520: // put the Frame actions in a hash and place that in global hash
1521: a = new FrameActions(this ).getActions();
1522: // i cant put table actions on fram since we dont know which jt
1523: // is selected at create time. this goes into each frame itself.
1524: ht = new LinkedHashMap(a.length);
1525: for (int i = 0; i < a.length; i++) {
1526: String name = (String) a[i].getValue(Action.NAME);
1527: ht.put(name, a[i]);
1528: }
1529: htActions.put("Frame", ht);
1530: //
1531: // put the List actions in a hash and place that in global hash
1532: a = new ListActions(this ).getActions();
1533: ht = new LinkedHashMap(a.length);
1534: for (int i = 0; i < a.length; i++) {
1535: String name = (String) a[i].getValue(Action.NAME);
1536: ht.put(name, a[i]);
1537: }
1538: List dynactions = TNS.getActions();
1539: if (dynactions != null) {
1540: Action ac;
1541: for (int i = 0; i < dynactions.size(); i++) {
1542: final Map /*<String,String>*/actmap = (Map) dynactions
1543: .get(i);
1544: final SQLForm _form = (SQLForm) this ;
1545: String name = (String) actmap.get("name");
1546: ac = new AbstractAction() {
1547: public boolean isEnabled() {
1548: return true;
1549: }
1550:
1551: public void actionPerformed(ActionEvent e) {
1552: String prompt = (String) actmap.get("prompt");
1553: String sqlpattern = (String) actmap
1554: .get("pattern");
1555:
1556: String[] commands = ListActions.formatCommand(
1557: _form, sqlpattern);
1558: ListActions.executeCommand(_form, commands,
1559: "prompt".equals(prompt));
1560:
1561: }
1562: };
1563: //a.putValue(Action.LONG_DESCRIPTION, value);
1564: ac.putValue(Action.NAME, name);
1565: //menuBookmark.add( a );
1566: ht.put(name, ac);
1567: } // for
1568: }
1569:
1570: htActions.put("List", ht);
1571: //System.err.println( "made action hash");
1572: }
1573:
1574: /* get a given Action for a category based on action name and category
1575: */
1576: protected Action getHashedAction(String category, String name) {
1577: // first get the relevant HashMap
1578: Map ht = (Map) htActions.get(category);
1579: // from there retrieve the action
1580: return (Action) ht.get(name);
1581: }
1582:
1583: /** get all the actions for a category.
1584: * RK added on 20040104 17:44:48
1585: * required to add all actions to a menu bar or popup.
1586: */
1587: protected Map getHashedActions(String category) {
1588: // first get the relevant HashMap
1589: return (Map) htActions.get(category);
1590: }
1591:
1592: public static void main(String[] args) {
1593: try {
1594: SQLForm sf = new SQLForm(args);
1595: // added window closing 20011013 else processes were getting
1596: // left open.
1597: sf.addWindowListener(new WindowAdapter() {
1598: public void windowClosing(WindowEvent e) {
1599: System.err.println("Shutting down..press enter.");
1600: System.exit(0);
1601: }
1602: });
1603:
1604: } catch (Exception ex) {
1605: new SQLExceptionPrint(ex);
1606: //throw new Exception();
1607: }
1608: }
1609:
1610: /** receives a ArrayList array containing column ArrayList nd data ArrayList,
1611: * and a table name (optional).
1612: * Depending on user preference, the 2 vetors are printed as text or
1613: * table.
1614: * This was added for show-column action
1615: */
1616: public void show(List[] vColRow, String name) {
1617: if (vColRow == null || name == null) {
1618: System.err.println("show1:Nothing to show");
1619: return;
1620: }
1621: if ("JTABLE".equalsIgnoreCase((String) getAttribute(
1622: "outputformat", "JTABLE"))) {
1623: TableMap tm = new TableMap(vColRow[0], vColRow[1]);
1624: if (tm == null) {
1625: System.err.println("show2:Nothing to show");
1626: return;
1627: }
1628: if ("single".equalsIgnoreCase((String) getAttribute(
1629: "tableview", "single"))) {
1630: tp.updateTable(tm);
1631: tp.makeTableAreaVisible();
1632: } else { // multiple
1633: tp.makeFramesVisible();
1634: tp.getWindowPanel().addFrame(tm, name);
1635: }
1636: } else { // TEXT format output
1637: StringBuffer result = IsqlUtil.printVector(vColRow, name);
1638: tp.appendOutputArea(result.toString());
1639: tp.makeOutputAreaVisible();
1640: }
1641: }// show
1642:
1643: public void maintainBookmark(String sql) {
1644: }
1645:
1646: /** given a filename, will load up all SQLs in it and put in a
1647: * JMenu.
1648: */
1649: public void bookmarkLoad(String fname) {
1650: SimpleParser sp = new SimpleParser();
1651: ParseModel pm = SimpleParser.createDefaultParseModel();
1652: try {
1653: sp.parse(fname, pm);
1654: Map ht = (HashMap) pm.getObject();
1655: if (ht.size() > 0) {
1656: if (htDynBookmarks == null)
1657: htDynBookmarks = new HashMap();
1658: htDynBookmarks.putAll((Map) pm.getObject());
1659: ActionListener al = new ActionListener() {
1660: public void actionPerformed(ActionEvent e) {
1661: tp
1662: .appendInputArea('\n' + (String) htDynBookmarks
1663: .get(e.getActionCommand()));
1664: }
1665: };
1666: Iterator e = ht.keySet().iterator();
1667: JMenu jm = new JMenu(fname);
1668:
1669: while (e.hasNext()) {
1670: final String key = (String) e.next();
1671: JMenuItem jmi = new JMenuItem(key);
1672: jmi.addActionListener(al);
1673: jm.add(jmi);
1674: }
1675: menubar.add(jm);
1676: menubar.invalidate();
1677: menubar.validate();
1678: menubar.repaint();
1679: }// ht.size
1680: else {
1681: popup("XML File doesnt contain bookmarks in correct format.");
1682: }
1683: } catch (Exception exc) {
1684: setErrorArea('\n' + "1424 :" + exc.toString());
1685: }
1686: } // bookmarkLoad
1687:
1688: public Bindings getBindings() {
1689: return bindings;
1690: }
1691:
1692: /** returns table names from table panel, so querying the db is
1693: * not required.
1694: * RK added on 20031227 12:09:11
1695: public String[] getTableNames(){
1696: ListModel lm = tablePanel.getModel();
1697: int size = lm.size();
1698: String tables[] = new String[ size ];
1699: for( int i = 0; i < size; i++){
1700: tables[i] = (String)lm.getElementAt(i);
1701: }
1702: return tables;
1703: }
1704: */
1705:
1706: public void waitCursor() {
1707: super .setCursor(java.awt.Cursor.WAIT_CURSOR);
1708: }
1709:
1710: public void defaultCursor() {
1711: super .setCursor(java.awt.Cursor.DEFAULT_CURSOR);
1712: }
1713:
1714: /** add to the masters map.
1715: * field, and the table:field:descfield to link to.
1716: */
1717: public void addToMaster(String field, String item) {
1718: if (!htMaster.containsKey(field)) {
1719: System.out.println(" htMaster:" + field + "-->" + item);
1720: htMaster.put(field, item);
1721: }
1722: }
1723:
1724: public Map getParams() {
1725: return htParams;
1726: }
1727:
1728: /** append the given line to the default ini file.
1729: * This method adds a new line.
1730: */
1731: public void appendToIni(String line) {
1732: appendToIni(line, inifile);
1733: }
1734:
1735: /** append the given line to the given ini file.
1736: * This method adds a new line.
1737: */
1738: public void appendToIni(String line, String filename) {
1739: try {
1740: BufferedWriter br = new BufferedWriter(new FileWriter(
1741: filename, true));
1742: br.write(line);
1743: br.write('\n');
1744: br.close();
1745: } catch (Exception exc) {
1746: System.err.println(P + " L 2040 EXC:" + exc.toString());
1747: exc.printStackTrace();
1748: }
1749:
1750: }
1751:
1752: /**
1753: * RK added on 20040201 12:19:10
1754: */
1755: public Map getBookmarkMap() {
1756: return htBookmarks;
1757: }
1758:
1759: public Map getLinkMap() {
1760: return htLinks;
1761: }
1762:
1763: public Map getMasterMap() {
1764: return htMaster;
1765: }
1766:
1767: public Map getSortMap() {
1768: return htSorts;
1769: }
1770:
1771: /** return map of filters to be used by Data and Construct fr a table.
1772: *
1773: * RK added on 20040202 17:13:38
1774: */
1775: public Map getFilterMap() {
1776: return htFilters;
1777: }
1778:
1779: public Map getRemembered() {
1780: return htRemembered;
1781: }
1782:
1783: public Map getAbbreviations() {
1784: return TNS.getAbbreviations();
1785: }
1786:
1787: public CommandHandler getCommandHandler() {
1788: return _commandHandler;
1789: }
1790:
1791: public static final String P = "SQLForm";
1792: } // class
|