0001: package isql;
0002:
0003: import java.io.*;
0004: import java.util.List;
0005: import java.awt.*;
0006: import java.util.*;
0007: import java.awt.event.ActionEvent;
0008: import java.text.*;
0009: import javax.swing.*;
0010: import javax.swing.KeyStroke;
0011: import javax.swing.SwingConstants;
0012: import javax.swing.text.*;
0013: import org.apache.oro.text.regex.*;
0014: import org.apache.oro.text.perl.*;
0015: import util.*;
0016:
0017: /**
0018: * @author Rahul Kumar $Author: rahul_kumar $
0019: * @version $Id: TableActions.java,v 1.7 2004/02/01 05:36:12 rahul_kumar Exp rahul $
0020: * XXX: these may bomb if selected from menubar and there is no data in
0021: * Table mode, thus need to check exceptions.
0022: * RK added on 20040111 19:32:42 - ignore case functionality
0023: *
0024: */
0025: public class TableActions {
0026:
0027: SQLForm _form = null;
0028:
0029: public static final int MATCHWORD = 1;
0030: public static final int REGEX = 2;
0031: public static final int MATCHCASE = 4;
0032: static PatternCompiler compiler = null;
0033: static PatternMatcher matcher = null;
0034:
0035: /** how many rows shown at a time. should pick from ini */
0036: public static final int PAGING_COUNT = 499;
0037:
0038: /** constructor passing whatever is needed. Do we need to pass
0039: * SQLString or give a method or what.
0040: */
0041: public TableActions(SQLForm form) {
0042: _form = form;
0043: }
0044:
0045: public Action[] getActions(JTable jt) {
0046: return new Action[] {
0047: new SetTableViewAction(_form),
0048: new InsertAction(_form, jt),
0049: new UpdateAction(_form, jt),
0050: new DeleteAction(_form, jt),
0051: new SortAction(_form, jt),
0052: new ReverseSortAction(_form, jt),
0053: new AskSortAction(_form, jt),
0054: new SearchAction(_form, jt),
0055: new RememberAction(_form, jt),
0056: new OverwriteRememberAction(_form, jt),
0057: new ClearSelectedRememberAction(_form, jt),
0058: new ClearRememberAction(_form, jt),
0059: //new SearchPartialMatchAction(_form, jt),
0060: //new SearchRegexMatchAction(_form, jt),
0061: //new SearchRegexPartialMatchAction(_form, jt),
0062: new GetLinkedInfoAction(_form, jt),
0063: new NextDataAction(_form, jt),
0064: new PreviousDataAction(_form, jt),
0065: new AskFilterAction(_form, jt),
0066: new DiscoverLinksAction(_form, jt) };
0067: }
0068:
0069: /** return a Map of keys and actions so that a user can
0070: * map the 2 automatically without changing his code for each new
0071: * mapping.
0072: */
0073: public static Map getActionMap(SQLForm _form, JTable jt) {
0074: Map map = new LinkedHashMap(32);
0075: map.put(setTableViewAction, new SetTableViewAction(_form));
0076: map.put(insertAction, new InsertAction(_form, jt));
0077: map.put(updateAction, new UpdateAction(_form, jt));
0078: map.put(deleteAction, new DeleteAction(_form, jt));
0079: map.put(sortAction, new SortAction(_form, jt));
0080: map.put(reversesortAction, new ReverseSortAction(_form, jt));
0081: map.put(asksortAction, new AskSortAction(_form, jt));
0082: map.put(searchAction, new SearchAction(_form, jt));
0083: map.put(rememberAction, new RememberAction(_form, jt));
0084: map.put(overwriteRememberAction, new OverwriteRememberAction(
0085: _form, jt));
0086: map
0087: .put(clearRememberAction, new ClearRememberAction(
0088: _form, jt));
0089: map.put(clearSelectedRememberAction,
0090: new ClearSelectedRememberAction(_form, jt));
0091: map
0092: .put(getLinkedInfoAction, new GetLinkedInfoAction(
0093: _form, jt));
0094: //map.put( searchPartialMatchAction, new SearchPartialMatchAction(_form, jt));
0095: //map.put( searchRegexMatchAction, new SearchRegexMatchAction(_form, jt));
0096: //map.put( searchRegexPartialMatchAction, new SearchRegexPartialMatchAction(_form, jt));
0097: map.put(nextDataAction, new NextDataAction(_form, jt));
0098: map.put(previousDataAction, new PreviousDataAction(_form, jt));
0099: map.put(askFilterAction, new AskFilterAction(_form, jt));
0100: map
0101: .put(discoverLinksAction, new DiscoverLinksAction(
0102: _form, jt));
0103: return map;
0104: }
0105:
0106: public static final String setTableViewAction = "set-tableview";
0107: public static final String rememberLastAction = "remember-last";
0108: public static final String saveStateAction = "save-state";
0109: public static final String insertAction = "insert-action";
0110: public static final String updateAction = "update-action";
0111: public static final String deleteAction = "delete-action";
0112: public static final String searchAction = "search-action";
0113: public static final String sortAction = "sort-action";
0114: public static final String reversesortAction = "reversesort-action";
0115: public static final String asksortAction = "ask-Sort";
0116: public static final String rememberAction = "remember-action";
0117: public static final String overwriteRememberAction = "overwriteremember-action";
0118: public static final String getLinkedInfoAction = "getlinkedinfo-action";
0119: public static final String clearSelectedRememberAction = "clearselectedremember-action";
0120: public static final String clearRememberAction = "clearremember-action";
0121: public static final String searchPartialMatchAction = "searchPartialMatchAction";
0122: public static final String searchRegexMatchAction = "searchRegexMatchAction";
0123: public static final String searchRegexPartialMatchAction = "searchRegexPartialMatchAction";
0124: public static final String nextDataAction = "next-Data";
0125: public static final String previousDataAction = "previous-Data";
0126: public static final String askFilterAction = "ask-Filter";
0127: public static final String discoverLinksAction = "discover-Links";
0128:
0129: public static class SetTableViewAction extends AbstractAction {
0130:
0131: public SetTableViewAction(SQLForm form) {
0132: super (setTableViewAction);
0133: this ._form = form;
0134: }
0135:
0136: final SQLForm _form;
0137:
0138: public void actionPerformed(ActionEvent e) {
0139: _form.setAttribute("tableview", "single");
0140: _form.setAttribute("outputformat", "jtable");
0141: }
0142: }
0143:
0144: public static class DiscoverLinksAction extends AbstractAction {
0145:
0146: public DiscoverLinksAction(SQLForm form, JTable _jt) {
0147: super (discoverLinksAction);
0148: this ._form = form;
0149: this .jt = _jt;
0150: putValue("accelerator", ((Map) _form.getBindings()
0151: .getBindingsForTable()).get(getValue(Action.NAME)));
0152: }
0153:
0154: final SQLForm _form;
0155: final JTable jt;
0156:
0157: public void actionPerformed(ActionEvent e) {
0158: //XXXXX
0159: System.out.println(" DISCOVER ACTION");
0160:
0161: String currtable = Actions.getTableFromSQL(
0162: _form._currentSQL, "<table>");
0163: List impkeys = _form.myjdbc.SQLGetImportedKeys(currtable); // XXX
0164: // mysql doesnt store these, so itll be null
0165: if (impkeys == null || impkeys.size() == 0) {
0166: //check if selected cols, else get index cols
0167: int[] cols = jt.getSelectedColumns();
0168: if (cols == null || cols.length == 0) {
0169: _form
0170: .popup("Please select a column to try linking on.");
0171: return;
0172: }
0173: // contains names of columns selected
0174: List selcols = JTableUtil.getSelectedColumnNames(jt);
0175: // joined string of selected columns
0176: String sthis keys = ArrayUtil.join(selcols, ',');
0177: //System.out.println( " thiskeys:"+ sthiskeys+".");
0178: List tables = _form.getAllTablePanelValues();
0179:
0180: // temp list to store primary keys of a table
0181: List l = new ArrayList();
0182: for (int i = 0; i < tables.size(); i++) {
0183: l.clear();
0184: String table = (String) tables.get(i);
0185: if (table.equals(currtable))
0186: continue;
0187: db.PrimaryKeyInfo pkinfo = _form.myjdbc
0188: .getPrimaryKeyInfoX(table);
0189: String skeys = pkinfo.getKeysAsString();
0190: int keyCount = pkinfo.getKeyCount();
0191: if (keyCount > 0) {
0192: //System.out.println( " "+ table +" has:"+skeys+".");
0193: boolean linked = false;
0194: if (keyCount > 1) {
0195: if (skeys.equals(sthis keys)) {
0196: linked = true;
0197: String link = "link " + currtable + ":"
0198: + sthis keys + ":" + table + ":"
0199: + skeys + ":" + skeys;
0200: System.out.println(link);
0201: _form.Run(link);
0202: _form.tp.putSQLInScrapArea(link);
0203: _form.addToMaster(sthis keys, table
0204: + ":" + skeys + ":" + skeys);
0205: }
0206: }
0207: if (!linked || keyCount == 1) {
0208: // look individually at each selected key
0209: for (int j = 0; j < selcols.size(); j++) {
0210: String field = (String) selcols.get(j);
0211: if (field.equals(skeys)) {
0212: String link = "link " + currtable
0213: + ":" + sthis keys + ":"
0214: + table + ":" + skeys + ":"
0215: + skeys;
0216: System.out.println(link);
0217: _form.Run(link);
0218: _form.tp.putSQLInScrapArea(link);
0219: _form
0220: .addToMaster(sthis keys,
0221: table + ":" + skeys
0222: + ":"
0223: + skeys);
0224: // this needs to be factored
0225: String sql = " select * from "
0226: + table + " where ";
0227: int[] rows = jt.getSelectedRows();
0228: // will bomb with a date
0229: for (int k = 0; k < rows.length; k++) {
0230: Object value = jt.getValueAt(
0231: rows[k], cols[j]);
0232: if (k > 0)
0233: sql += " OR ";
0234: sql += skeys + "='" + value
0235: + "'";
0236: }
0237: _form.Run(sql);
0238: }
0239: }
0240: }
0241: }
0242:
0243: } // for each table
0244:
0245: }
0246:
0247: }
0248: }
0249:
0250: /** generates SQL for deleting selected row.
0251: * BUG TODO: uses tablename of last sql executed
0252: * which may not be the correct one. */
0253: public static class DeleteAction extends AbstractAction {
0254:
0255: public DeleteAction(SQLForm form, JTable jt) {
0256: super (deleteAction);
0257: this ._form = form;
0258: this .jt = jt;
0259: putValue("accelerator", "DELETE");
0260: }
0261:
0262: final SQLForm _form;
0263: final JTable jt;
0264:
0265: public void actionPerformed(ActionEvent e) {
0266: //JTable jt = (JTable) _form.tp.getActualComponent(no);
0267: int[] rows = jt.getSelectedRows();
0268: int colcount = jt.getColumnCount();
0269: StringBuffer sb = new StringBuffer(64);
0270: String shortclass = null;
0271: String sepStart = null, sepEnd = null;
0272: TableMap tm = (TableMap) jt.getModel();
0273: String table = null;
0274: if (tm != null)
0275: table = Actions.getTableFromSQL(tm.getSQL(), "<table>");
0276: else
0277: table = Actions.getTableFromSQL(_form._currentSQL,
0278: "<table>");
0279: for (int j = 0; j < rows.length; j++) {
0280:
0281: sb.append("\ndelete from " + table + " where \n");
0282: for (int i = 0; i < colcount; i++) {
0283: Class c = jt.getColumnClass(i);
0284: // we retrieve class name less package and derive
0285: // user-definable start and finish string for each
0286: // value to be printed
0287: int pos = c.getName().lastIndexOf('.');
0288: if (pos != -1)
0289: shortclass = c.getName().substring(pos + 1)
0290: .toLowerCase();
0291: else
0292: shortclass = c.getName().toLowerCase();
0293: // delimiters
0294: // e.g. fs_string, fs_integer, fs_double, fs_date,
0295: // fs_timestamp
0296: sepStart = (String) _form.getAttribute("fs_"
0297: + shortclass, "'");
0298: sepEnd = (String) _form.getAttribute("fe_"
0299: + shortclass, "'");
0300:
0301: Object o = jt.getValueAt(rows[j], i);
0302:
0303: sb.append(jt.getColumnName(i) + " = " + sepStart
0304: + jt.getValueAt(rows[j], i) + sepEnd);
0305: if (i < colcount - 1)
0306: sb.append(" and ").append('\n');
0307: } // for i
0308: } // for j
0309: _form.tp.appendInputArea(sb.toString());
0310: System.out.println(sb.toString());
0311:
0312: } //action performed
0313:
0314: } // delete
0315:
0316: public static class InsertAction extends AbstractAction {
0317:
0318: public InsertAction(SQLForm form, JTable jt) {
0319: super (insertAction);
0320: this ._form = form;
0321: this .jt = jt;
0322: putValue("accelerator", "INSERT");
0323: }
0324:
0325: final SQLForm _form;
0326: final JTable jt;
0327:
0328: public void actionPerformed(ActionEvent e) {
0329: //JTable jt = (JTable) _form.tp.getActualComponent(no);
0330: int[] rows = jt.getSelectedRows();
0331: int colcount = jt.getColumnCount();
0332: StringBuffer sb = new StringBuffer(64);
0333: String shortclass = null;
0334: String sepStart = null, sepEnd = null;
0335: // XXX need to take table name from tablemap and test for
0336: // both single and multiple
0337: String table = null;
0338: // attempt to get table from Map since the last SQL may not
0339: // be the one that resulted in this JInt frame.
0340: TableMap tm = (TableMap) jt.getModel();
0341: if (tm != null)
0342: table = tm.getTableName(1);
0343: if (table == null || table.trim().length() == 0)
0344: table = Actions.getTableFromSQL(tm.getSQL(), "<table>");
0345:
0346: for (int j = 0; j < rows.length; j++) {
0347:
0348: sb.append("\ninsert into " + table + " values ( \n");
0349: for (int i = 0; i < colcount; i++) {
0350: Class c = jt.getColumnClass(i);
0351: // we retrieve class name less package and derive
0352: // user-definable start and finish string for each
0353: // value to be printed
0354: int pos = c.getName().lastIndexOf('.');
0355: if (pos != -1)
0356: shortclass = c.getName().substring(pos + 1)
0357: .toLowerCase();
0358: else
0359: shortclass = c.getName().toLowerCase();
0360: // delimiters
0361: // e.g. fs_string, fs_integer, fs_double, fs_date,
0362: // fs_timestamp
0363: sepStart = (String) _form.getAttribute("fs_"
0364: + shortclass, "'");
0365: sepEnd = (String) _form.getAttribute("fe_"
0366: + shortclass, "'");
0367:
0368: Object o = jt.getValueAt(rows[j], i);
0369:
0370: sb.append(sepStart + jt.getValueAt(rows[j], i)
0371: + sepEnd + " /* " + jt.getColumnName(i)
0372: + " */");
0373: if (i < colcount - 1)
0374: sb.append(" , ").append('\n');
0375: } // for i
0376: sb.append(")\n");
0377: } // for j
0378: _form.tp.appendInputArea(sb.toString());
0379: System.out.println(sb.toString());
0380:
0381: } //action performed
0382:
0383: } // delete
0384:
0385: /** generate an update script for the row selected.
0386: * I think we need to have an option of putting only those fields
0387: * that are selected rather than all. All is a pain most times.
0388: */
0389: public static class UpdateAction extends AbstractAction {
0390:
0391: public UpdateAction(SQLForm form, JTable jt) {
0392: super (updateAction);
0393: this ._form = form;
0394: this .jt = jt;
0395: putValue("accelerator", "alt U");
0396: }
0397:
0398: final SQLForm _form;
0399: final JTable jt;
0400:
0401: public void actionPerformed(ActionEvent e) {
0402: //JTable jt = (JTable) _form.tp.getActualComponent(no);
0403: int[] rows = jt.getSelectedRows();
0404: int colcount = jt.getColumnCount();
0405: StringBuffer sb = new StringBuffer(64);
0406: StringBuffer sbset = new StringBuffer(64);
0407: StringBuffer sbwhere = new StringBuffer(64);
0408: String shortclass = null;
0409: String sepStart = null, sepEnd = null;
0410: // retrieve table name from SQL
0411: // XXX we need to take from tablemap object
0412: String table = null;
0413: // RK added on 20040201 11:05:49
0414: // oracle does not return the tablename in metadata thus
0415: // there will be wrong tables sometimes.
0416: TableMap tm = (TableMap) jt.getModel();
0417: if (tm != null) {
0418: table = tm.getTableName(1);
0419: }
0420: if (table == null || table.trim().length() == 0)
0421: table = Actions.getTableFromSQL(tm.getSQL(), "<table>");
0422:
0423: for (int j = 0; j < rows.length; j++) {
0424:
0425: sb.append("\nUPDATE " + table + " SET\n");
0426: for (int i = 0; i < colcount; i++) {
0427: Class c = jt.getColumnClass(i);
0428: // we retrieve class name less package and derive
0429: // user-definable start and finish string for each
0430: // value to be printed
0431: int pos = c.getName().lastIndexOf('.');
0432: if (pos != -1)
0433: shortclass = c.getName().substring(pos + 1)
0434: .toLowerCase();
0435: else
0436: shortclass = c.getName().toLowerCase();
0437: // delimiters
0438: // e.g. fs_string, fs_integer, fs_double, fs_date,
0439: // fs_timestamp
0440: sepStart = (String) _form.getAttribute("fs_"
0441: + shortclass, "'");
0442: sepEnd = (String) _form.getAttribute("fe_"
0443: + shortclass, "'");
0444:
0445: Object o = jt.getValueAt(rows[j], i);
0446:
0447: sbset.append(jt.getColumnName(i) + " = " + sepStart
0448: + jt.getValueAt(rows[j], i) + sepEnd);
0449: sbwhere.append(jt.getColumnName(i) + " = "
0450: + sepStart + jt.getValueAt(rows[j], i)
0451: + sepEnd);
0452: if (i < colcount - 1) {
0453: sbset.append(" , ").append('\n');
0454: sbwhere.append(" and ").append('\n');
0455: }
0456: } // for i
0457: } // for j
0458: sb.append(sbset).append("\nwhere ").append(sbwhere);
0459: _form.tp.appendInputArea(sb.toString());
0460: System.out.println(sb.toString());
0461:
0462: } //action performed
0463:
0464: } // update
0465:
0466: /** Action for searching/finding rows containing a value.
0467: * TODO: Now use showOptionDialog and ask for whole word, regex,
0468: * match case, along with word. then we can combine into one action.
0469: */
0470: public static class SearchAction extends AbstractAction {
0471:
0472: public SearchAction(SQLForm form, JTable jt) {
0473: super (searchAction);
0474: this ._form = form;
0475: this .jt = jt;
0476: putValue("accelerator", ((Map) _form.getBindings()
0477: .getBindingsForTable()).get(getValue(Action.NAME)));
0478: }
0479:
0480: final SQLForm _form;
0481: final JTable jt;
0482:
0483: public void actionPerformed(ActionEvent e) {
0484:
0485: JCheckBox cbmatch = new JCheckBox("Match whole field",
0486: false);
0487: JCheckBox cbregex = new JCheckBox("Use regex", false);
0488: JCheckBox cbcase = new JCheckBox("Match case", false);
0489: JLabel label = new JLabel("Search in column for:",
0490: JLabel.LEFT);
0491: JTextField text = new JTextField(20);
0492: JPanel p = new JPanel();
0493: p.setLayout(new GridLayout(3, 2, 2, 5)); // rows, cols, hgap, vgap
0494: p.add(label);
0495: p.add(text);
0496: p.add(cbmatch);
0497: p.add(cbregex);
0498: p.add(cbcase);
0499:
0500: int i = JOptionPane.showOptionDialog(null, p,
0501: "Search Result", JOptionPane.OK_CANCEL_OPTION,
0502: JOptionPane.PLAIN_MESSAGE, null, null, null);
0503: if (i == JOptionPane.CANCEL_OPTION)
0504: return;
0505: // XXXX
0506: int bitmask = 0;
0507: if (cbmatch.isSelected())
0508: bitmask = bitmask | MATCHWORD;
0509: if (cbregex.isSelected())
0510: bitmask |= REGEX;
0511: if (cbcase.isSelected())
0512: bitmask |= MATCHCASE;
0513: String s = text.getText().trim();
0514: if (s == null || s.length() == 0)
0515: return;
0516: int found = searchaction(_form, jt, s, bitmask);
0517: }
0518: }
0519:
0520: /** common method to search for a string/pattern. Based on
0521: * searchtype.
0522: * returns the number of matches, or 0 if none. if user cancels,
0523: * returns a -1.
0524: */
0525: public static int searchaction(SQLForm _form, JTable jt, String ss,
0526: int searchtype) {
0527:
0528: //String s = _form.getInput(message);
0529: if (ss == null || ss.trim().length() == 0)
0530: return -1;
0531: int[] cols = jt.getSelectedColumns();
0532: if (cols == null || cols.length == 0) {
0533: _form.popup("Please select a column to search on.");
0534: return -1;
0535: }
0536: int[] rows = jt.getSelectedRows();
0537: TableMap tm = (TableMap) jt.getModel();
0538: for (int i = 0; i < rows.length; i++) {
0539: jt.removeRowSelectionInterval(rows[i], rows[i]);
0540: }
0541:
0542: String s = ss;
0543: if ((searchtype & MATCHCASE) == 0)
0544: s = s.toUpperCase();
0545:
0546: Pattern pattern = null;
0547: if ((searchtype & REGEX) == REGEX) {
0548: if (compiler == null)
0549: compiler = new Perl5Compiler();
0550: if (matcher == null)
0551: matcher = new Perl5Matcher();
0552: try {
0553: pattern = compiler.compile(s);
0554: //pattern = compiler.compile(s, Perl5Compiler.CASE_INSENSITIVE_MASK);
0555: } catch (MalformedPatternException exc) {
0556: _form.popup("Sorry. Malformed pattern.");
0557: System.err.println(P + " L 358 EXC:" + exc.toString());
0558: exc.printStackTrace();
0559: return -1;
0560: }
0561: }
0562:
0563: int found = 0;
0564: int rowcount = tm.getRowCount();
0565: int firstcol = 0;
0566:
0567: for (int i = 0; i < rowcount; i++) {
0568: String val = tm.getValueAt(i, cols[0]).toString();
0569: if ((searchtype & MATCHCASE) == 0)
0570: val = val.toUpperCase();
0571:
0572: boolean matched = false;
0573: if ((searchtype & MATCHWORD) == MATCHWORD
0574: && (searchtype & REGEX) == 0)
0575: matched = s.equals(val);
0576: else if ((searchtype & MATCHWORD) == 0
0577: && (searchtype & REGEX) == 0)
0578: matched = (val.indexOf(s) > -1);
0579: else if ((searchtype & MATCHWORD) == MATCHWORD
0580: && (searchtype & REGEX) == REGEX)
0581: matched = matcher.matches(val, pattern);
0582: else if ((searchtype & MATCHWORD) == 0
0583: && (searchtype & REGEX) == REGEX)
0584: matched = matcher.contains(val, pattern);
0585: if (matched) {
0586: jt.addRowSelectionInterval(i, i);
0587: // save the first match since we will scroll to it
0588: if (firstcol == 0)
0589: firstcol = i;
0590: found++;
0591: }
0592: }
0593:
0594: if (found == 0)
0595: _form.popup("[" + ss + "] not found");
0596: // RK added on 20040101 01:18:32
0597: // added to scroll down to the first match
0598: Rectangle rect = jt.getCellRect(firstcol, cols[0], true);
0599: jt.scrollRectToVisible(rect);
0600: return found;
0601: } // searchaction
0602:
0603: public static class SortAction extends AbstractAction {
0604:
0605: public SortAction(SQLForm form, JTable jt) {
0606: super (sortAction);
0607: this ._form = form;
0608: this .jt = jt;
0609: putValue("accelerator", ((Map) _form.getBindings()
0610: .getBindingsForTable()).get(getValue(Action.NAME)));
0611: }
0612:
0613: final SQLForm _form;
0614: final JTable jt;
0615:
0616: public void actionPerformed(ActionEvent e) {
0617: int[] cols = jt.getSelectedColumns();
0618: TableMap tm = (TableMap) jt.getModel();
0619: tm.sort(cols, true); // true means ascending
0620: jt.repaint();
0621: }
0622: }
0623:
0624: public static class ReverseSortAction extends AbstractAction {
0625:
0626: public ReverseSortAction(SQLForm form, JTable jt) {
0627: super (reversesortAction);
0628: this ._form = form;
0629: this .jt = jt;
0630: putValue("accelerator", ((Map) _form.getBindings()
0631: .getBindingsForTable()).get(getValue(Action.NAME)));
0632: }
0633:
0634: final SQLForm _form;
0635: final JTable jt;
0636:
0637: public void actionPerformed(ActionEvent e) {
0638: try {
0639: int[] cols = jt.getSelectedColumns();
0640: TableMap tm = (TableMap) jt.getModel();
0641: tm.sort(cols, false); // false means descending
0642: jt.repaint();
0643: } catch (Exception exc) {
0644: System.err.println(" L 319 EXC:" + exc.toString());
0645: exc.printStackTrace();
0646:
0647: _form
0648: .popup("This applies to Table mode. Do you have output in the Table tab? If using Frames, use the key or right-click.");
0649: }
0650: }
0651: }
0652:
0653: /** ask user what fields to sort on. User may enter field names or
0654: * offsets starting 0, with commas in between.
0655: */
0656: public static class AskSortAction extends AbstractAction {
0657:
0658: public AskSortAction(SQLForm form, JTable jt) {
0659: super (asksortAction);
0660: this ._form = form;
0661: this .jt = jt;
0662: putValue("accelerator", ((Map) _form.getBindings()
0663: .getBindingsForTable()).get(getValue(Action.NAME)));
0664: }
0665:
0666: final SQLForm _form;
0667: final JTable jt;
0668:
0669: public void actionPerformed(ActionEvent e) {
0670: String s = _form
0671: .getInput("Enter fields to sort on (comma separated, start 0, for descending append -) e.g. 0,3-,5");
0672: if (s == null || s.trim().length() == 0)
0673: return;
0674:
0675: String fields[] = ArrayUtil.split(s, ',');
0676: TableMap tm = (TableMap) jt.getModel();
0677: // since the columns are padded with spaces
0678: // i need to trim them. this is a Source of bugs !!!
0679: List lold = (List) tm.getColumns();
0680: List columns = new ArrayList(lold.size());
0681: for (int i = 0; i < lold.size(); i++) {
0682: columns
0683: .add(((String) lold.get(i)).trim()
0684: .toUpperCase());
0685: }
0686: int[] cols = new int[fields.length];
0687: int[] sorder = new int[fields.length];
0688: int k;
0689: boolean showcolumns = false;
0690: for (int i = 0; i < fields.length; i++) {
0691: k = i;
0692: // try for offset, then fieldname
0693: String field = fields[i].trim();
0694:
0695: // RK added on 20040103 16:44:21
0696: // check for order character
0697: // if ends with - then reverse, else ascending
0698: if (field.endsWith("-")) {
0699: sorder[i] = -1;
0700: field = field.substring(0, field.length() - 1);
0701: } else if (field.endsWith("+")) {
0702: sorder[i] = 1;
0703: field = field.substring(0, field.length() - 1);
0704: } else
0705: sorder[i] = 1;
0706:
0707: try {
0708: k = Integer.parseInt(field);
0709: } catch (NumberFormatException exc) {
0710: k = columns.indexOf(field.toUpperCase());
0711: if (k == -1) {
0712: System.out.println("Error: Couldnt find "
0713: + field);
0714: _form.setErrorArea("Error: Couldnt find field:"
0715: + field);
0716: showcolumns = true;
0717: k = i;
0718: }
0719: }
0720: cols[i] = k;
0721: }
0722: if (showcolumns) {
0723: StringBuffer sb = new StringBuffer(64);
0724: for (int i = 0; i < columns.size(); i++) {
0725: sb.append(columns.get(i)).append(',');
0726: }
0727: _form.popup("Columns are:" + sb.toString());
0728: return;
0729:
0730: }
0731: tm.sort(cols, sorder); // false means descending
0732: jt.repaint();
0733: }
0734: }
0735:
0736: /** ask user what value/range to filter to. User may enter values or
0737: * a range using a ':' character.
0738: * Discrete values use a comma delim - not yet.
0739: * WORKS but the overwrite previous is not reliable. needs
0740: * thought.
0741: * TODO unable to get the initial focus on the text box
0742: */
0743: public static class AskFilterAction extends AbstractAction {
0744:
0745: public AskFilterAction(SQLForm form, JTable jt) {
0746: super (askFilterAction);
0747: this ._form = form;
0748: this .jt = jt;
0749: putValue("accelerator", ((Map) _form.getBindings()
0750: .getBindingsForTable()).get(getValue(Action.NAME)));
0751: }
0752:
0753: final SQLForm _form;
0754: final JTable jt;
0755:
0756: public void actionPerformed(ActionEvent e) {
0757: JCheckBox jcb = new JCheckBox("Overwrite previous", true);
0758: JLabel label = new JLabel(
0759: "Enter value or range to filter on", JLabel.LEFT);
0760: JTextField text = new JTextField(20);
0761: JPanel p = new JPanel();
0762: p.setLayout(new GridLayout(2, 2, 2, 5)); // rows, cols, hgap, vgap
0763: p.add(label);
0764: p.add(text);
0765: p.add(jcb);
0766: // boolean b = text.requestFocusInWindow();
0767: // System.out.println( " req focus in window b="+b);
0768:
0769: int i = JOptionPane.showOptionDialog(null, p,
0770: "Enter Filter", JOptionPane.OK_CANCEL_OPTION,
0771: JOptionPane.PLAIN_MESSAGE, null, null, null);
0772: if (i == JOptionPane.CANCEL_OPTION)
0773: return;
0774:
0775: //String s = _form.getInput("Enter value/s or range to filter on (comma delimited):");
0776: String s = text.getText();
0777: if (s == null || s.trim().length() == 0)
0778: return;
0779: int cols[] = jt.getSelectedColumns();
0780: int rows[] = jt.getSelectedRows();
0781:
0782: // if no row, no data in table and user used popup.
0783: if (cols == null) {
0784: return;
0785: }
0786: int col = cols[0]; // take first col at present
0787: // XXXX
0788: TableMap tm = (TableMap) jt.getModel();
0789: int type = tm.getType(col);
0790: String fieldname = tm.getColumnName(col);
0791: Object currentvalue = jt.getValueAt(rows[0], col);
0792:
0793: String formattedstring = formatFilter(s, type, tm
0794: .getColumnName(col), currentvalue, _form
0795: .getParams());
0796: System.out.println("formatted:" + formattedstring);
0797: System.out.println("old:" + tm.whereCondition);
0798: //String oldwhere = tm.whereCondition;
0799: String oldsql = tm.getSQL();
0800: if (jcb.isSelected() && tm.whereCondition != null)
0801: oldsql = tm.whereCondition;
0802: //tm.whereCondition=formattedstring;
0803: String newsql = formatCondition(oldsql, formattedstring,
0804: null, jcb.isSelected());
0805: System.out.println("NEW SQL:" + newsql);
0806:
0807: _form.setErrorArea("\nAttempting sql:" + newsql);
0808: _form.waitCursor();
0809: TableMap tmnew = null;
0810: try {
0811: tmnew = (TableMap) _form.myjdbc.runSelect(newsql);
0812: } catch (Exception exc) {
0813: _form.tp.putSQLInScrapArea(newsql);
0814: _form.defaultCursor();
0815: _form.popup("Check error in History tab and retry:\n"
0816: + exc.toString());
0817: return;
0818: }
0819: _form.defaultCursor();
0820: _form.tp.putSQLInScrapArea(newsql);
0821: if (jcb.isSelected())
0822: tmnew.whereCondition = oldsql;
0823: else
0824: tmnew.whereCondition = newsql;
0825: System.out.println("old now has:" + tm.whereCondition);
0826:
0827: if (tmnew.getRowCount() == 0) {
0828: _form
0829: .popup("No data returned. Pls check the SQL in History tab and try.");
0830: return;
0831: }
0832: jt.setModel(tmnew);
0833: }
0834: }
0835:
0836: /** adds the given where cond to the TRIVIAL sql.
0837: * It does not replace previous sqls, it keeps appending. so you
0838: * cant keep playing with it. How to address this ??
0839: * Simple implementation, it will bomb if you have a field ending
0840: * with WHERE, or the case of where is different, where doesnt have
0841: * a space or there is no WHERE, but other clauses exist.
0842: * FIXME XXX
0843: * TODO work on floats, ints etc also.
0844: */
0845: public static String formatCondition(String sql, String where,
0846: String oldwhere, boolean overwrite) {
0847:
0848: int pos = -1;
0849: // remove the last where condition
0850: //System.out.println( "OLD:"+oldwhere + ":"+ overwrite);
0851: //if (oldwhere != null && overwrite){
0852: // System.out.println(" removing:"+oldwhere);
0853: // sql = util.Util.replace(oldwhere, "", sql);
0854: // System.out.println( "sql after remove:"+sql+"]");
0855: //}
0856: if ((pos = sql.indexOf("WHERE ")) > -1) {
0857: sql = util.Util.replace("WHERE ", "WHERE " + where
0858: + " AND ", sql);
0859: return sql;
0860: }
0861: // very naive implementation assuming there is no group by order
0862: // by etc.
0863: sql = sql + " WHERE " + where;
0864: return sql;
0865: }
0866:
0867: /**
0868: * valid formats for date
0869: * [:]([+-](\d+)[mdyw]+)[:]($1)?
0870: * t = +0 = -0 = '=' = todays date only
0871: * M = current month
0872: * Y = current year
0873: * +1M = next month (entire month, start to end)
0874: * +1Y = next year (entire year, start to end)
0875: * +1 = eq to tomorrow
0876: * -1 = eq yesterday
0877: * +1m = eq the day one month hence
0878: * :+1m = upto next month (same date)
0879: * :-1m = upto last month (same date as today)
0880: * -1m: = from last month onwards
0881: * -1m:+1m = last month to next month
0882: *
0883: *
0884: */
0885: public static String formatFilter(String s, int type,
0886: String columnname, Object currentvalue, Map params) {
0887: String ret = "";
0888: //System.out.println( "type:"+type+" s:"+s+" colname:"+columnname);
0889: switch (type) {
0890: case java.sql.Types.VARCHAR:
0891: case java.sql.Types.CHAR:
0892: ret = formatCharWherePortion(s, columnname,
0893: (String) currentvalue);
0894: break;
0895: case java.sql.Types.TIMESTAMP:
0896: case java.sql.Types.DATE:
0897: //String f = DateResolver.formatDate(s);
0898: ret = formatDateWherePortion(s, columnname, currentvalue
0899: .toString(), params);
0900: break;
0901: case java.sql.Types.INTEGER:
0902: case java.sql.Types.DOUBLE:
0903: case java.sql.Types.FLOAT:
0904: case java.sql.Types.REAL:
0905: case java.sql.Types.NUMERIC:
0906: case java.sql.Types.TINYINT:
0907: case java.sql.Types.BIGINT:
0908: case java.sql.Types.SMALLINT:
0909:
0910: ret = formatIntWherePortion(s, columnname, currentvalue
0911: .toString());
0912: break;
0913: default:
0914: System.out.println(" DEFAULT FILTER TODO ");
0915: break;
0916:
0917: }
0918: return ret;
0919: }
0920:
0921: /** format the where portion of a string with columnname and
0922: * formatted date part.
0923: * @param f formatted date returned by DateResolver usually as a
0924: * jdbc date or dates with a ':' defining a range.
0925: */
0926: public static String formatDateWherePortion(String f,
0927: String columnname, String currentvalue, Map params) {
0928: // single date
0929: String defop = " = ";
0930: if (currentvalue != null)
0931: currentvalue = DateResolver.getDBString(currentvalue,
0932: params);
0933:
0934: // evaluate shortcuts first and return
0935: if (f.equals("=")) {
0936: f = currentvalue;
0937: return columnname + defop + currentvalue;
0938: } else if (f.equals(">") || f.equals(">=") || f.equals("<")
0939: || f.equals("<=") || f.equals("!=")) {
0940: defop = f;
0941: f = currentvalue;
0942: return columnname + defop + currentvalue;
0943: }
0944:
0945: // evaluate ranges and our codes d,m,y etc
0946: f = DateResolver.formatDate(f);
0947:
0948: String ret = "";
0949: if (f.indexOf(':') == -1) {
0950: ret = columnname + " = "
0951: + DateResolver.getDBString(f, params);
0952: } else {
0953: // date range
0954: String p[] = ArrayUtil.split(f, ':');
0955: boolean addand = false;
0956: if (p[0] != null && p[0].length() > 0) {
0957: ret += columnname + " >= "
0958: + DateResolver.getDBString(p[0], params) + " ";
0959: addand = true;
0960: }
0961: if (p.length == 2)
0962: if (p[1] != null && p[1].length() > 0) {
0963: if (addand)
0964: ret += " AND ";
0965: ret += " " + columnname + " < "
0966: + DateResolver.getDBString(p[1], params)
0967: + " ";
0968: }
0969: }
0970: return ret;
0971: }
0972:
0973: /** format the where portion of a string with columnname and
0974: * int range.
0975: * @param f
0976: */
0977: public static String formatIntWherePortion(String f,
0978: String columnname, String currentvalue) {
0979: // single date
0980: String defop = " = ";
0981: String shortm[] = PerlWrapper.perlMatch("^([=!><]{1,2})$", f);
0982: String doublem[] = PerlWrapper.perlMatch(
0983: "([=!><]{1,2})([^=!><]+)", f);
0984: if (shortm != null) {
0985: defop = shortm[0];
0986: f = currentvalue;
0987: } else if (doublem != null) {
0988: defop = doublem[0];
0989: f = doublem[1];
0990: }
0991:
0992: String ret = "";
0993: if (f.indexOf(':') == -1) {
0994: ret = columnname + defop + f + " ";
0995: } else {
0996: // int range
0997: String p[] = ArrayUtil.split(f, ':');
0998: boolean addand = false;
0999: if (p[0] != null && p[0].length() > 0) {
1000: ret += columnname + " >= " + p[0] + " ";
1001: addand = true;
1002: }
1003: if (p.length == 2)
1004: if (p[1] != null && p[1].length() > 0) {
1005: if (addand)
1006: ret += " AND ";
1007: ret += " " + columnname + " < " + p[1] + " ";
1008: }
1009: }
1010: return ret;
1011: }
1012:
1013: /** format the where portion of a string with columnname and
1014: * int range.
1015: * @param f
1016: */
1017: public static String formatCharWherePortion(String f,
1018: String columnname, String currentvalue) {
1019: // single date
1020: String defop = " = ";
1021: currentvalue = "'" + currentvalue + "'";
1022:
1023: String shortm[] = PerlWrapper.perlMatch("^([=!><]{1,2})$", f);
1024: String doublem[] = PerlWrapper.perlMatch(
1025: "([=!><]{1,2})([^=!><]+)", f);
1026: if (shortm != null) {
1027: defop = shortm[0];
1028: f = currentvalue;
1029: } else if (doublem != null) {
1030: defop = doublem[0];
1031: f = "'" + doublem[1] + "'";
1032: }
1033: String ret = "";
1034: if (f.indexOf(':') == -1) {
1035: //ret = columnname + defop +currentvalue+" ";
1036: if (f.charAt(0) != '\'')
1037: f = "'" + f + "'";
1038: ret = columnname + defop + f + " ";
1039: } else {
1040: // date range
1041: String p[] = ArrayUtil.split(f, ':');
1042: boolean addand = false;
1043: if (p[0] != null && p[0].length() > 0) {
1044: ret += columnname + " >= '" + p[0] + "' ";
1045: addand = true;
1046: }
1047: if (p.length == 2)
1048: if (p[1] != null && p[1].length() > 0) {
1049: if (addand)
1050: ret += " AND ";
1051: ret += " " + columnname + " < '" + p[1] + "' ";
1052: }
1053: }
1054: return ret;
1055: }
1056:
1057: /** saves selected values to application memory.
1058: * these will then be used for smarter linking.
1059: */
1060: public static class RememberAction extends AbstractAction {
1061:
1062: public RememberAction(SQLForm form, JTable jt) {
1063: super (rememberAction);
1064: this ._form = form;
1065: this .jt = jt;
1066: putValue("accelerator", ((Map) _form.getBindings()
1067: .getBindingsForTable()).get(getValue(Action.NAME)));
1068: }
1069:
1070: final SQLForm _form;
1071: final JTable jt;
1072:
1073: public void actionPerformed(ActionEvent e) {
1074: //System.out.println( "remember action ");
1075: remember(_form, jt, false);
1076: }
1077: } // remembered action
1078:
1079: /** saves selected values to application memory overwriting existing
1080: * ones for same field.
1081: * these will then be used for smarter linking.
1082: */
1083: public static class OverwriteRememberAction extends AbstractAction {
1084:
1085: public OverwriteRememberAction(SQLForm form, JTable jt) {
1086: super (overwriteRememberAction);
1087: this ._form = form;
1088: this .jt = jt;
1089: putValue("accelerator", ((Map) _form.getBindings()
1090: .getBindingsForTable()).get(getValue(Action.NAME)));
1091: }
1092:
1093: final SQLForm _form;
1094: final JTable jt;
1095:
1096: public void actionPerformed(ActionEvent e) {
1097: remember(_form, jt, true);
1098: }
1099: } // class
1100:
1101: /** called by the 2 remember actions, one with overwrite true, and
1102: * one with false.
1103: */
1104: protected static void remember(SQLForm _form, JTable jt,
1105: boolean overwrite) {
1106: Map map = _form.htRemembered;
1107: if (map == null) {
1108: _form.htRemembered = new HashMap();
1109: map = _form.htRemembered;
1110: }
1111: int[] cols = jt.getSelectedColumns();
1112: int[] rows = jt.getSelectedRows();
1113: TableMap tm = (TableMap) jt.getModel();
1114: // for each selected column, make a list of
1115: // values and add that to remembered values
1116: for (int j = 0; j < cols.length; j++) {
1117: List l = new ArrayList(rows.length);
1118: String colname = tm.getColumnName(cols[j]).trim();
1119: for (int i = 0; i < rows.length; i++) {
1120: Object val = tm.getValueAt(rows[i], cols[j]);
1121: //System.out.println( "remember:"+colname+":"+val);
1122: _form.setErrorArea(" Yanked " + colname + ":" + val
1123: + ".");
1124: l.add(val);
1125: }
1126: if (map.get(colname) == null || overwrite)
1127: map.put(colname, l);
1128: else {
1129: ((List) map.get(colname)).addAll(l);
1130: }
1131: } // for each col
1132: } // remember
1133:
1134: /** determines master table for this field, and runs a query on that
1135: * table with a where condition matching selected data, displays that
1136: * data.
1137: * Uses only the first selected column, but all rows of that column.
1138: * RK 2003/12/26
1139: */
1140: public static class GetLinkedInfoAction extends AbstractAction {
1141:
1142: public GetLinkedInfoAction(SQLForm form, JTable jt) {
1143: super (getLinkedInfoAction);
1144: this ._form = form;
1145: this .jt = jt;
1146: putValue("accelerator", ((Map) _form.getBindings()
1147: .getBindingsForTable()).get(getValue(Action.NAME)));
1148: }
1149:
1150: final SQLForm _form;
1151: final JTable jt;
1152:
1153: public void actionPerformed(ActionEvent e) {
1154: int cols[] = jt.getSelectedColumns();
1155: int rows[] = jt.getSelectedRows();
1156: //System.out.println( "XXX value si "+value);
1157: TableMap tm = (TableMap) jt.getModel();
1158: String possibleTable = Actions.getTableFromSQL(tm.getSQL(),
1159: "<table>");
1160: // since the columns are padded with spaces
1161: // i need to trim them. UGH !!!
1162: List lold = (List) tm.getColumns();
1163: List columns = new ArrayList(lold.size());
1164: for (int i = 0; i < lold.size(); i++) {
1165: columns.add(((String) lold.get(i)).trim());
1166: }
1167: String key = null;
1168: String column = (String) columns.get(cols[0]);
1169: String tablename = null;
1170: if (column.indexOf('.') == -1) {
1171: //tablename = Actions.getTableFromSQL(_form._currentSQL,"<table>");
1172: // RK added on 20031229 16:17:25
1173: tablename = tm.getTableName(cols[0]);
1174: if (tablename == null || tablename.trim().length() == 0) {
1175: System.err
1176: .println("DB Driver didnt give tablename. Guessing:"
1177: + possibleTable);
1178: tablename = possibleTable;
1179: }
1180: //System.out.println(" Tablename for column:"+tablename);
1181: key = tablename + "." + column;
1182: } else {
1183: key = column;
1184: String a[] = ArrayUtil.split(key, '.');
1185: tablename = a[0];
1186: column = a[1];
1187: }
1188: //System.out.println( "Key is:"+key);
1189: boolean fulllink = false;
1190: String link = _form.getLink(key);
1191: if (link == null) {
1192: fulllink = true;
1193: System.out.println("Warning: No link found for:" + key);
1194: _form.setErrorArea(" No link found for: [" + key + "]");
1195: if (fulllink)
1196: link = promptForFullLink(_form, jt, tablename,
1197: column);
1198: else
1199: link = promptForLink(_form, jt, tablename, column);
1200: if (link == null)
1201: return;
1202: // promptForLink returns t.c for other table
1203: if (!fulllink)
1204: link = link.replace('.', ':');
1205: System.out.println("Created Link:" + link);
1206: }
1207: String alink[] = ArrayUtil.split(link, ':');
1208: String linktable = null;
1209: String linkfield = null;
1210: if (fulllink) {
1211: linktable = alink[2];
1212: linkfield = alink[3];
1213: } else {
1214: linktable = alink[0];
1215: linkfield = alink[1];
1216: }
1217: //String sql = " select * from "+linktable+" where "+linkfield+"='"+value+"'";
1218: // take the value from multiple columns
1219: String sql = " select * from " + linktable + " where ";
1220: for (int i = 0; i < rows.length; i++) {
1221: Object value = jt.getValueAt(rows[i], cols[0]);
1222: if (i > 0)
1223: sql += " OR ";
1224: sql += linkfield + "='" + value + "'";
1225: }
1226: _form.Run(sql);
1227: if (fulllink) {
1228: _form.Run("link " + link);
1229: _form
1230: .setErrorArea("Created Link- [link "
1231: + link
1232: + "]. Pls paste into ini file for future sessions.");
1233: _form.tp.putSQLInScrapArea("link " + link);
1234: // RK added on 20040126 19:20:17
1235: _form.appendToIni("link " + link);
1236: }
1237:
1238: }
1239: } // class
1240:
1241: public static String promptForLink(SQLForm _form, JTable jt,
1242: String oldtable, String oldcolumn) {
1243:
1244: // RK added on 20031231 16:31:58 made last param numm so you can
1245: // selfjoin
1246: String table = promptForTable(_form, jt,
1247: "Select a link table:", null);
1248: if (table == null || table.trim().length() == 0)
1249: return null;
1250: String column = promptForColumn(_form, jt,
1251: "Select a link column:", table, oldcolumn);
1252: if (column == null || column.trim().length() == 0)
1253: return null;
1254: return table + "." + column;
1255: }
1256:
1257: /** popup for selecting a table, with given message/prompt.
1258: * The list will now show the suppressed table. No longer used,
1259: * since we often need a self-join.
1260: */
1261: public static String promptForTable(SQLForm _form, JTable jt,
1262: String message, String suppress) {
1263: List tables = _form.getAllTablePanelValues();
1264: if (suppress != null)
1265: tables.remove(suppress);
1266: String t[] = ArrayUtil.toStringArray(tables);
1267: String selected = (String) _form.getInput(message, "Table:", t,
1268: t[0]);
1269: return selected;
1270: }
1271:
1272: public static String promptForColumn(SQLForm _form, JTable jt,
1273: String message, String tablename, String possiblecolumn) {
1274: if (tablename == null)
1275: return null;
1276: List cols = null;
1277: try {
1278: cols = _form.myjdbc.getColumnNames(tablename);
1279: } catch (Exception exc) {
1280: System.err.println(P + " L EXC:" + exc.toString());
1281: exc.printStackTrace();
1282: }
1283: if (cols == null)
1284: return null;
1285:
1286: String c[] = ArrayUtil.toStringArray(cols);
1287: int match = 0;
1288: // try to find the closest column as a default in the list.
1289: if (possiblecolumn != null) {
1290: match = getClosestPossibleMatch(c, possiblecolumn);
1291: if (match == -1)
1292: match = 0;
1293: }
1294: String selected = (String) _form.getInput(message, "Column:",
1295: c, c[match]);
1296: System.out.println("cols returning:" + selected);
1297: return selected;
1298: }
1299:
1300: /** prompts user for full link which can then be saved in session
1301: * for constructSQL and other programs to use. This adds a
1302: * descriptive field to pick up once it has linked.
1303: */
1304: public static String promptForFullLink(SQLForm _form, JTable jt,
1305: String oldtable, String oldcolumn) {
1306: // RK added on 20031231 16:31:58 made last param numm so you can
1307: // selfjoin
1308: String table = promptForTable(_form, jt,
1309: "Select a link table:", null);
1310: if (table == null || table.trim().length() == 0)
1311: return null;
1312: String column = promptForColumn(_form, jt,
1313: "Select a link column:", table, oldcolumn);
1314: if (column == null || column.trim().length() == 0)
1315: return null;
1316:
1317: List cols = null;
1318: try {
1319: cols = _form.myjdbc.getColumnNames(table);
1320: } catch (Exception exc) {
1321: System.err.println(P + " L EXC:" + exc.toString());
1322: exc.printStackTrace();
1323: }
1324: if (cols == null)
1325: return null;
1326: cols.remove(column);
1327: int match = 0;
1328: if (cols.size() > 1)
1329: match = 1;
1330: String acols[] = ArrayUtil.toStringArray(cols);
1331:
1332: String desc_col_regex = _form.getAttribute("desccolumn");
1333: match = getClosestDescriptiveColumn(acols, column, match,
1334: desc_col_regex);
1335:
1336: String desccolumn = (String) _form.getInput(
1337: "Select a descriptive column:", "Column:", acols,
1338: acols[match]);
1339:
1340: if (desccolumn == null || desccolumn.trim().length() == 0)
1341: return null;
1342: return oldtable + ':' + oldcolumn + ':' + table + ":" + column
1343: + ":" + desccolumn;
1344: }
1345:
1346: /** finds the index of the closest field to the given one.
1347: * First checks for exact match, then partial matches. Used during
1348: * linking tables.
1349: */
1350: public static int getClosestPossibleMatch(String[] arr, String col) {
1351: int index = ArrayUtil.indexOf(arr, col);
1352: if (index != -1)
1353: return index;
1354:
1355: index = ArrayUtil.indexOfEndsWith(arr, col);
1356: if (index != -1)
1357: return index;
1358:
1359: index = ArrayUtil.indexOfEndsWith(col, arr);
1360: return index;
1361: }
1362:
1363: public static int getClosestDescriptiveColumn(String[] acols,
1364: String linkcolumn, int defaultindex, String desc_col_regex) {
1365: if (desc_col_regex == null)
1366: desc_col_regex = "/(desc$|description$|Name$)/i";
1367: int index = ArrayUtil.indexOfRegex(acols, desc_col_regex);
1368: if (index == -1)
1369: return defaultindex;
1370: return index;
1371: }
1372:
1373: /** this will take an SQL statement with fields ($abc) and
1374: * substitute them with values from table if such rows and columns
1375: * exist */
1376: public static String substituteFields(String value, SQLForm _form,
1377: int no) {
1378:
1379: JTable jt = (JTable) _form.tp.getActualComponent(no);
1380: int[] rows = jt.getSelectedRows();
1381: if (rows.length == 0)
1382: return value;
1383: int colcount = jt.getColumnCount();
1384: StringBuffer sb = new StringBuffer(64);
1385: String shortclass = null;
1386: String sepStart = null, sepEnd = null;
1387: String fields[] = PerlWrapper.perlMatch("(\\$[\\w_]+)", value);
1388: for (int j = 0; j < rows.length; j++) {
1389: String newvalue = value;
1390: for (int k = 0; k < fields.length; k++) {
1391:
1392: String name = null;
1393: for (int i = 0; i < colcount; i++) {
1394: name = jt.getColumnName(i).trim();
1395: if (!name.equals(fields[k].substring(1)))
1396: continue;
1397: Object o = jt.getValueAt(rows[j], i);
1398: newvalue = PerlWrapper.perlSubstitute("s/\\"
1399: + fields[k] + "/" + o + "/g", newvalue);
1400: } // for i
1401: } // for k
1402: sb.append(newvalue);
1403: sb.append("\n;");
1404: } // for j
1405: return (sb.toString());
1406: } //subs
1407:
1408: /** clear the yank/remember Map.
1409: */
1410: public static class ClearRememberAction extends AbstractAction {
1411:
1412: public ClearRememberAction(SQLForm form, JTable jt) {
1413: super (clearRememberAction);
1414: this ._form = form;
1415: this .jt = jt;
1416: putValue("accelerator", ((Map) _form.getBindings()
1417: .getBindingsForTable()).get(getValue(Action.NAME)));
1418: }
1419:
1420: final SQLForm _form;
1421: final JTable jt;
1422:
1423: public void actionPerformed(ActionEvent e) {
1424: if (_form.htRemembered == null)
1425: return;
1426: _form.htRemembered = null;
1427: _form.setErrorArea(" Cleared yank table.");
1428: }
1429: } // class
1430:
1431: /** clear given field/s from the yank/remember hashtable.
1432: * oesnt work when called rfom menu since it doesnt know which
1433: * jtable.
1434: */
1435: public static class ClearSelectedRememberAction extends
1436: AbstractAction {
1437:
1438: public ClearSelectedRememberAction(SQLForm form, JTable jt) {
1439: super (clearSelectedRememberAction);
1440: this ._form = form;
1441: this .jt = jt;
1442: putValue("accelerator", ((Map) _form.getBindings()
1443: .getBindingsForTable()).get(getValue(Action.NAME)));
1444: }
1445:
1446: final SQLForm _form;
1447: final JTable jt;
1448:
1449: public void actionPerformed(ActionEvent e) {
1450: int cols[] = jt.getSelectedColumns();
1451: // RK added on 20031229 13:09:23
1452: if (cols == null) {
1453: System.out.println(" No Column. Try using the keys. ");
1454: _form
1455: .setErrorArea("\nNo field selected. Use keys instead.\n");
1456: }
1457: if (cols == null || cols.length == 0)
1458: return;
1459: for (int i = 0, col = cols[0]; i < cols.length; col = cols[i++]) {
1460: String field = ((String) ((List) ((TableMap) jt
1461: .getModel()).getColumns()).get(col)).trim();
1462: //System.out.println(" field to unyank:"+ field);
1463: Object removed = _form.htRemembered.remove(field);
1464: if (removed == null)
1465: _form.setErrorArea("\nNo mapping for [" + field
1466: + "] in yank table.\n");
1467: else
1468: _form.setErrorArea("\nRemoved mapping for:" + field
1469: + " from yank table.");
1470: }
1471: }
1472: } // class
1473:
1474: /** fetch more data for current query.
1475: */
1476: public static class NextDataAction extends AbstractAction {
1477:
1478: public NextDataAction(SQLForm form, JTable jt) {
1479: super (nextDataAction);
1480: this ._form = form;
1481: this .jt = jt;
1482: putValue("accelerator", ((Map) _form.getBindings()
1483: .getBindingsForTable()).get(getValue(Action.NAME)));
1484: }
1485:
1486: final SQLForm _form;
1487: final JTable jt;
1488:
1489: public void actionPerformed(ActionEvent e) {
1490: // XXXX
1491: if (jt == null || !(jt.getModel() instanceof TableMap)) {
1492: _form
1493: .popup("Please click on a table. Use the control-D key if this isnt working.");
1494: return;
1495: }
1496: TableMap tm = (TableMap) jt.getModel();
1497: if (!tm.moreRows()) {
1498: _form.popup(" No next data.");
1499: return;
1500: }
1501: int endrow = tm.getEndRow() + 1;
1502: String sql = tm.getSQL();
1503: _form.waitCursor();
1504: TableMap tmnew = null;
1505: try {
1506: tmnew = (TableMap) _form.myjdbc.runSelect(sql, endrow,
1507: endrow + PAGING_COUNT); // 500 to be picked from ini
1508: } catch (Exception exc) {
1509: _form.defaultCursor();
1510: _form.popup(exc.toString());
1511: return;
1512:
1513: }
1514: _form.setErrorArea("\nExecuted for " + endrow + " to "
1515: + (endrow + PAGING_COUNT));
1516: jt.setModel(tmnew);
1517: }
1518: } // class
1519:
1520: /** fetch more data for current query.
1521: */
1522: public static class PreviousDataAction extends AbstractAction {
1523:
1524: public PreviousDataAction(SQLForm form, JTable jt) {
1525: super (previousDataAction);
1526: this ._form = form;
1527: this .jt = jt;
1528: putValue("accelerator", ((Map) _form.getBindings()
1529: .getBindingsForTable()).get(getValue(Action.NAME)));
1530: }
1531:
1532: final SQLForm _form;
1533: final JTable jt;
1534:
1535: public void actionPerformed(ActionEvent e) {
1536: // XXXX
1537: if (jt == null) {
1538: _form
1539: .popup("Please click on a table. Use the key if this isnt working.");
1540: return;
1541: }
1542: TableMap tm = (TableMap) jt.getModel();
1543: int startrow = tm.getStartRow();
1544: if (startrow == 0) {
1545: _form.popup(" No previous data.");
1546: return;
1547: }
1548: startrow = Math.max(startrow - (1 + PAGING_COUNT), 0);
1549:
1550: int endrow = startrow + PAGING_COUNT;
1551: String sql = tm.getSQL();
1552: _form.waitCursor();
1553: TableMap tmnew = null;
1554: try {
1555: tmnew = (TableMap) _form.myjdbc.runSelect(sql,
1556: startrow, endrow); // 500 to be picked from ini
1557: } catch (Exception exc) {
1558: _form.popup(exc.toString());
1559:
1560: _form.defaultCursor();
1561: return;
1562: }
1563: _form.defaultCursor();
1564: _form.setErrorArea("\nExecuted for " + startrow + " to "
1565: + endrow + ". ");
1566: jt.setModel(tmnew);
1567: }
1568: } // class
1569:
1570: public static final String P = "TableActions";
1571: } // outer class
|