From: SVN by r. <sv...@ca...> - 2008-08-03 20:03:09
|
Author: roy Date: 2008-08-03 22:03:00 +0200 (Sun, 03 Aug 2008) New Revision: 281 Modified: src/main/java/nl/improved/sqlclient/AbstractSQLShellWindow.java src/main/java/nl/improved/sqlclient/DBConnector.java src/main/java/nl/improved/sqlclient/jcurses/SQLShellWindow.java Log: made connector not dependant on jcurses.. added initial implementation for dump binary data Modified: src/main/java/nl/improved/sqlclient/AbstractSQLShellWindow.java =================================================================== --- src/main/java/nl/improved/sqlclient/AbstractSQLShellWindow.java 2008-08-03 20:01:43 UTC (rev 280) +++ src/main/java/nl/improved/sqlclient/AbstractSQLShellWindow.java 2008-08-03 20:03:00 UTC (rev 281) @@ -53,6 +53,7 @@ import javax.xml.transform.sax.SAXTransformerFactory; import javax.xml.transform.sax.TransformerHandler; import javax.xml.transform.stream.StreamResult; +import nl.improved.sqlclient.DBConnector.ConnectionSettings; import nl.improved.sqlclient.commands.*; import nl.improved.sqlclient.util.LimitedArrayList; import org.w3c.dom.Document; @@ -61,6 +62,7 @@ import org.w3c.dom.NodeList; import org.xml.sax.SAXException; import org.xml.sax.helpers.AttributesImpl; +import sun.misc.BASE64Encoder; /** * The SQLShell abstract main class. @@ -481,6 +483,8 @@ * @param p the character x/y location to show the popupscreen on */ public abstract String select(List<String> items, Point p); + + protected abstract String[] getLoginCredentials(String username, String password) throws SQLException; /** * Returns the connection to the database * @return the connection to the database @@ -978,7 +982,7 @@ /** * Connect command for setting up a connection to a database. */ - private static class ConnectCommand implements Command { + private class ConnectCommand implements Command { /** * Execute the connection command and return a readable result. * @param command the command string for setting up a connection @@ -992,8 +996,11 @@ if (cmdString.length() > 0 && cmdString.charAt(cmdString.length()-1) == ';') { cmdString = cmdString.substring(0, cmdString.length()-1); } - DBConnector.getInstance().connect(cmdString); - return "Connected.\n\n"; + if (connect(cmdString) != null) { + return "Connected.\n\n"; + } else { + return "Connect failed. Unknown reason\n\n"; + } } catch(SQLException e) { throw new IllegalStateException("Failed to connect: " + e.getMessage(), e); } @@ -1057,6 +1064,88 @@ public boolean backgroundProcessSupported() { return false; } + + /** + * Connects to a database, using a connection string. + * + * Possible cases: + * <table> + * <tr> + * <td>"user/pass@ident"</td> + * <td>Connects to ident as user with password pass</td> + * </tr> + * <tr> + * <td>"user/@ident"</td> + * <td>Connects to ident connection as user with empty password</td> + * </tr> + * <tr> + * <td>"user@ident"</td> + * <td>Connects to ident connection as user, without specifying a password (will be prompted for pass)</td> + * </tr> + * <tr> + * <td>"@ident"</td> + * <td>Connects to ident connection, without specifying user or password. If default user is specified that will be used, if not: will be prompted for user/pass</td> + * </tr> + * <tr> + * <td>"user/pass"</td> + * <td>Connects to default connection as user, with password pass</td> + * </tr> + * <tr> + * <td>"user/"</td> + * <td>Connects to default connection as user, with empty password</td> + * </tr> + * <tr> + * <td>"user"</td> + * <td>Connects to default connection as user, without specifying a password (will be prompted for pass)</td> + * </tr> + * <tr> + * <td>""</td> + * <td>Connects to default connection, without specifying user or password. If default user is specified that will be used, if not: will be prompted for user/pass</td> + * </tr> + * <table> + * + * @param connectString the connect string, following the conditions as specified above. + * @return the opened Connection + * @throws SQLException if the connection could not be opened. + */ + public Connection connect(String connectString) throws SQLException { + //Shortcut - no need to try and parse everything if we already know we're empty + DBConnector dbConnector = DBConnector.getInstance(); + String ident = dbConnector.getDefaultIdentifier(); + String username = null; + String password = null; + if (connectString != null && connectString.trim().length() > 0) { + + String[] connectParts = connectString.split("@"); + if (connectParts.length > 1) { + ident = connectParts[1].trim(); + } + + if (connectParts[0].matches(".+/.*")) { + String[] loginDetails = connectParts[0].split("/"); + if (loginDetails.length > 1) { + password = loginDetails[1]; + } else { + password = ""; + } + username = loginDetails[0].trim(); + } else { + username = connectParts[0].trim(); + } + } + if (username == null || password == null) { + ConnectionSettings predefinedSettings = dbConnector.getPredefinedConnectionSettings(ident); + if (predefinedSettings != null) { + username = predefinedSettings.getUsername(); + password = predefinedSettings.getPassword(); + } + String[] credentials = getLoginCredentials(username, password); + username = credentials[0]; + password = credentials[1]; + } + + return dbConnector.connect(ident, username, password); + } } /** * Command that enables the user to close a connection. @@ -1415,7 +1504,7 @@ TransformerHandler hd = tf.newTransformerHandler(); Transformer serializer = hd.getTransformer(); serializer.setOutputProperty(OutputKeys.ENCODING,"ISO-8859-1"); - serializer.setOutputProperty(OutputKeys.INDENT,"yes"); + //serializer.setOutputProperty(OutputKeys.INDENT,"no"); hd.setResult(streamResult); hd.startDocument(); AttributesImpl atts = new AttributesImpl(); @@ -1445,12 +1534,34 @@ } else if (metaData.getColumnType(col) == Types.BINARY || metaData.getColumnType(col) == Types.BLOB || metaData.getColumnType(col) == Types.CLOB || - metaData.getColumnType(col) == Types.LONGNVARCHAR) { - InputStream valueStream = rs.getBinaryStream(col); - //Base64 + metaData.getColumnType(col) == Types.LONGNVARCHAR || + metaData.getColumnType(col) == Types.LONGVARBINARY || + metaData.getColumnType(col) == Types.LONGVARCHAR || + metaData.getColumnType(col) == Types.NCLOB || + metaData.getColumnType(col) == Types.OTHER) { atts.addAttribute("","","type","","binary"); hd.startElement("","","col",atts); + + BASE64Encoder enc = new BASE64Encoder(); + int bytesSize = 128; + byte[] bytes = new byte[bytesSize]; + int read; + InputStream valueStream = rs.getBinaryStream(col); + while ( (read = valueStream.read(bytes)) != -1) { + if (read == 0) { + continue; + } + if (read != bytes.length) { + bytes = Arrays.copyOf(bytes, read); + } + String stringValue = enc.encode(bytes) +"\n"; + hd.characters(stringValue.toCharArray(), 0, stringValue.length()); + if (bytes.length != bytesSize) { + bytes = new byte[bytesSize]; + } + } } else { + atts.addAttribute("","","type","",metaData.getColumnTypeName(col)); hd.startElement("","","col",atts); String value= rs.getString(col); if (value != null) { Modified: src/main/java/nl/improved/sqlclient/DBConnector.java =================================================================== --- src/main/java/nl/improved/sqlclient/DBConnector.java 2008-08-03 20:01:43 UTC (rev 280) +++ src/main/java/nl/improved/sqlclient/DBConnector.java 2008-08-03 20:03:00 UTC (rev 281) @@ -27,20 +27,9 @@ import java.util.Set; import java.util.Map; import java.util.Properties; -import jcurses.system.InputChar; -import jcurses.event.ActionEvent; -import jcurses.event.ActionListener; -import jcurses.widgets.Button; -import jcurses.widgets.Dialog; -import jcurses.widgets.GridLayoutManager; -import jcurses.widgets.Label; -import jcurses.widgets.PasswordField; -import jcurses.widgets.TextField; -import jcurses.widgets.WidgetsConstants; public final class DBConnector { - /** * The default formatting pattern for Date or Date-like columns. */ @@ -119,79 +108,7 @@ return null; } - /** - * Connects to a database, using a connection string. - * - * Possible cases: - * <table> - * <tr> - * <td>"user/pass@ident"</td> - * <td>Connects to ident as user with password pass</td> - * </tr> - * <tr> - * <td>"user/@ident"</td> - * <td>Connects to ident connection as user with empty password</td> - * </tr> - * <tr> - * <td>"user@ident"</td> - * <td>Connects to ident connection as user, without specifying a password (will be prompted for pass)</td> - * </tr> - * <tr> - * <td>"@ident"</td> - * <td>Connects to ident connection, without specifying user or password. If default user is specified that will be used, if not: will be prompted for user/pass</td> - * </tr> - * <tr> - * <td>"user/pass"</td> - * <td>Connects to default connection as user, with password pass</td> - * </tr> - * <tr> - * <td>"user/"</td> - * <td>Connects to default connection as user, with empty password</td> - * </tr> - * <tr> - * <td>"user"</td> - * <td>Connects to default connection as user, without specifying a password (will be prompted for pass)</td> - * </tr> - * <tr> - * <td>""</td> - * <td>Connects to default connection, without specifying user or password. If default user is specified that will be used, if not: will be prompted for user/pass</td> - * </tr> - * <table> - * - * @param connectString the connect string, following the conditions as specified above. - * @return the opened Connection - * @throws SQLException if the connection could not be opened. - */ - public Connection connect(String connectString) throws SQLException { - //Shortcut - no need to try and parse everything if we already know we're empty - if (connectString == null || connectString.trim().length() == 0) { - return connect(defaultConnector, null, null); - } - String ident = defaultConnector; - String username = null; - String password = null; - - String[] connectParts = connectString.split("@"); - if (connectParts.length > 1) { - ident = connectParts[1].trim(); - } - - if (connectParts[0].matches(".+/.*")) { - String[] loginDetails = connectParts[0].split("/"); - if (loginDetails.length > 1) { - password = loginDetails[1]; - } else { - password = ""; - } - username = loginDetails[0].trim(); - } else { - username = connectParts[0].trim(); - } - - return connect(getPredefinedConnectionSettings(ident), username, password); - } - public QueryExecutor getQueryExecutor() { if (queryExecutor == null) { if (dateIsTimeStamp) { @@ -203,7 +120,7 @@ return queryExecutor; } - private ConnectionSettings getPredefinedConnectionSettings(String identifier) { + public ConnectionSettings getPredefinedConnectionSettings(String identifier) { if (predefinedConnections.containsKey(identifier)) { return predefinedConnections.get(identifier); } @@ -271,16 +188,6 @@ } } - if (username == null || password == null) { - LoginDialog ld = new LoginDialog(username, password); - ld.show(); - if (!ld.exitOk) { - throw new SQLException("Connect cancelled."); - } - username = ld.getUsername(); - password = ld.getPassword(); - } - activeConnection = DriverManager.getConnection(settings.getConnectionURL(), username, password); activeConnection.setAutoCommit(autoCommit); // INITIALIZE database settings @@ -342,7 +249,7 @@ return statement; } - private static class ConnectionSettings { + public static class ConnectionSettings { private String identifier; private String connectionURL; private String driver; @@ -386,100 +293,4 @@ return password; } } - - private static class LoginDialog extends Dialog { - private boolean exitOk = false; - private TextField userfield; - private PasswordField passfield; - - public LoginDialog(final String username, final String password) { - super(10,10, 50, 7, true,"Connect"); - userfield = new TextField(); - setUsername(username); - passfield = new PasswordField() { - - @Override - protected void focus() { - super.focus(); - } - - protected boolean handleInput(InputChar ch) { - if (!ch.isSpecialCode() && ch.getCharacter() == '\n') { - okButtonPressedSlot(); - return false; - } - return super.handleInput(ch); - } - }; - setPassword(password); - - Button okButton = new Button("Ok"); - okButton.addListener(new ActionListener() { - public void actionPerformed(ActionEvent event) { - okButtonPressedSlot(); - } - }); - Button cancelButton = new Button("Cancel"); - cancelButton.addListener(new ActionListener() { - public void actionPerformed(ActionEvent arg0) { - LoginDialog.this.exitOk = false; - LoginDialog.this.close(); - } - }); - - GridLayoutManager glm = new GridLayoutManager(4,3); - getRootPanel().setLayoutManager(glm); - - glm.addWidget(new Label("Username"), 0,0,1,1, WidgetsConstants.ALIGNMENT_CENTER, WidgetsConstants.ALIGNMENT_LEFT); - glm.addWidget(userfield, 1,0,3,1, WidgetsConstants.ALIGNMENT_CENTER, WidgetsConstants.ALIGNMENT_LEFT); - glm.addWidget(new Label("Password"), 0,1,1,1, WidgetsConstants.ALIGNMENT_CENTER, WidgetsConstants.ALIGNMENT_LEFT); - glm.addWidget(passfield, 1,1,3,1, WidgetsConstants.ALIGNMENT_CENTER, WidgetsConstants.ALIGNMENT_LEFT); - - glm.addWidget(okButton, 1,2,1,1, WidgetsConstants.ALIGNMENT_CENTER, WidgetsConstants.ALIGNMENT_CENTER); - glm.addWidget(cancelButton, 2,2,1,1, WidgetsConstants.ALIGNMENT_CENTER, WidgetsConstants.ALIGNMENT_CENTER); - - } - public void okButtonPressedSlot() { - exitOk = true; - close(); - } - - @Override - protected void activate() { - super.activate(); - - if (userfield.getText().length() == 0) { - userfield.getFocus(); - } else if (passfield.getText().length() == 0) { - passfield.getFocus(); - } else { - throw new IllegalStateException("We have login data, but get a login dailog anyway."); - } - } - - public void setUsername(String username) { - if (username == null) { - userfield.setText(""); - } else { - userfield.setText(username); - } - } - - public String getUsername() { - return userfield.getText(); - } - - public void setPassword(String password) { - if (password == null) { - passfield.setText(""); - } else { - passfield.setText(password); - } - } - - public String getPassword() { - return passfield.getText(); - } - } - } Modified: src/main/java/nl/improved/sqlclient/jcurses/SQLShellWindow.java =================================================================== --- src/main/java/nl/improved/sqlclient/jcurses/SQLShellWindow.java 2008-08-03 20:01:43 UTC (rev 280) +++ src/main/java/nl/improved/sqlclient/jcurses/SQLShellWindow.java 2008-08-03 20:03:00 UTC (rev 281) @@ -15,13 +15,23 @@ */ package nl.improved.sqlclient.jcurses; +import java.sql.SQLException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import jcurses.event.ActionEvent; +import jcurses.event.ActionListener; import jcurses.system.CharColor; import jcurses.system.InputChar; import jcurses.system.Toolkit; +import jcurses.widgets.Button; +import jcurses.widgets.Dialog; +import jcurses.widgets.GridLayoutManager; +import jcurses.widgets.Label; +import jcurses.widgets.PasswordField; import jcurses.widgets.PopUpMenu; +import jcurses.widgets.TextField; +import jcurses.widgets.WidgetsConstants; import jcurses.widgets.Window; import nl.improved.sqlclient.AbstractSQLShellWindow; import nl.improved.sqlclient.InputKey; @@ -245,6 +255,21 @@ } } + @Override + protected String[] getLoginCredentials(String username, String password) throws SQLException { + LoginDialog diag = new LoginDialog(username, password); + dontRepaint = true; + try { + diag.show(); + if (!diag.exitOk) { + throw new SQLException("Connect cancelled."); + } + return new String[] {diag.getUsername(), diag.getPassword() }; + } finally { + dontRepaint = false; + } + } + /** * Override to allow painting on the main thread to overcome painting errors. */ @@ -263,6 +288,104 @@ Toolkit.beep(); } + private static class LoginDialog extends Dialog { + private boolean exitOk = false; + private TextField userfield; + private PasswordField passfield; + + public LoginDialog(final String username, final String password) { + super(10,10, 50, 7, true,"Connect"); + userfield = new TextField(); + setUsername(username); + passfield = new PasswordField() { + + @Override + protected void focus() { + super.focus(); + } + + @Override + protected boolean handleInput(InputChar ch) { + if (!ch.isSpecialCode() && ch.getCharacter() == '\n') { + okButtonPressedSlot(); + return false; + } + return super.handleInput(ch); + } + }; + setPassword(password); + + Button okButton = new Button("Ok"); + okButton.addListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent event) { + okButtonPressedSlot(); + } + }); + Button cancelButton = new Button("Cancel"); + cancelButton.addListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent arg0) { + LoginDialog.this.exitOk = false; + LoginDialog.this.close(); + } + }); + + GridLayoutManager glm = new GridLayoutManager(4,3); + getRootPanel().setLayoutManager(glm); + + glm.addWidget(new Label("Username"), 0,0,1,1, WidgetsConstants.ALIGNMENT_CENTER, WidgetsConstants.ALIGNMENT_LEFT); + glm.addWidget(userfield, 1,0,3,1, WidgetsConstants.ALIGNMENT_CENTER, WidgetsConstants.ALIGNMENT_LEFT); + glm.addWidget(new Label("Password"), 0,1,1,1, WidgetsConstants.ALIGNMENT_CENTER, WidgetsConstants.ALIGNMENT_LEFT); + glm.addWidget(passfield, 1,1,3,1, WidgetsConstants.ALIGNMENT_CENTER, WidgetsConstants.ALIGNMENT_LEFT); + + glm.addWidget(okButton, 1,2,1,1, WidgetsConstants.ALIGNMENT_CENTER, WidgetsConstants.ALIGNMENT_CENTER); + glm.addWidget(cancelButton, 2,2,1,1, WidgetsConstants.ALIGNMENT_CENTER, WidgetsConstants.ALIGNMENT_CENTER); + + } + public void okButtonPressedSlot() { + exitOk = true; + close(); + } + + @Override + protected void activate() { + super.activate(); + + if (userfield.getText().length() == 0) { + userfield.getFocus(); + } else if (passfield.getText().length() == 0) { + passfield.getFocus(); + } else { + throw new IllegalStateException("We have login data, but get a login dailog anyway."); + } + } + + public void setUsername(String username) { + if (username == null) { + userfield.setText(""); + } else { + userfield.setText(username); + } + } + + public String getUsername() { + return userfield.getText(); + } + + public void setPassword(String password) { + if (password == null) { + passfield.setText(""); + } else { + passfield.setText(password); + } + } + + public String getPassword() { + return passfield.getText(); + } + } + public static void main(String[] args) { SQLShellWindow shell = new SQLShellWindow(); shell.show(); |