1 package jimm.datavision.source.sql; 2 import jimm.datavision.*; 3 import jimm.datavision.source.*; 4 import jimm.util.XMLWriter; 5 import jimm.util.I18N; 6 import java.sql.*; 7 import java.util.*; 8 9 14 public class Database extends DataSource { 15 16 protected static final String [] DB_OBJECT_TYPES = { "TABLE", "VIEW" }; 17 18 protected String driverClassName; 19 protected String connInfo; 20 protected String name; 21 protected String username; 22 protected TreeMap tables; 23 protected HashMap tableCacheMap; 24 protected String schemaName; 25 protected Connection conn; 26 private String password; 27 protected boolean hasPassword; 28 protected boolean connectionOwnedByMe; 29 protected boolean storesLowerCaseIdentifiers; 30 protected boolean storesUpperCaseIdentifiers; 31 32 public Database(Connection conn, Report report) throws SQLException { 33 super(report, new SQLQuery(report)); 34 35 this.driverClassName = ""; 36 this.connInfo = ""; 37 this.name = ""; 38 this.username = ""; 39 this.password = ""; hasPassword = true; 41 tables = null; 42 43 this.conn = conn; 44 connectionOwnedByMe = false; 45 loadAllTables(); 46 } 47 48 57 public Database(String driverClassName, String connInfo, Report report, 58 String name, String user) 59 throws SQLException, ClassNotFoundException , InstantiationException , 60 IllegalAccessException , UserCancellationException 61 { 62 this(driverClassName, connInfo, report, name, user, null, false); 63 } 64 65 75 public Database(String driverClassName, String connInfo, Report report, 76 String name, String user, String password) 77 throws SQLException, ClassNotFoundException , InstantiationException , 78 IllegalAccessException , UserCancellationException 79 { 80 this(driverClassName, connInfo, report, name, user, password, true); 81 } 82 83 84 96 protected Database(String driverClassName, String connInfo, Report report, 97 String name, String user, String password, 98 boolean givenPassword) 99 throws SQLException, ClassNotFoundException , InstantiationException , 100 IllegalAccessException , UserCancellationException 101 { 102 super(report, new SQLQuery(report)); 103 104 this.driverClassName = driverClassName; 105 this.connInfo = connInfo; 106 this.name = name; 107 this.username = (user == null) ? "" : user; 108 this.password = password; 109 tables = null; 110 hasPassword = givenPassword; 111 112 initializeConnection(); 113 loadAllTables(); 114 } 115 116 public boolean canJoinTables() { return true; } 117 public boolean isSQLGenerated() { return true; } 118 public boolean isConnectionEditable() { return true; } 119 public boolean areRecordsSelectable() { return true; } 120 public boolean areRecordsSortable() { return true; } 121 public boolean canGroupRecords() { return true; } 122 123 133 public Column findColumn(Object id) { 134 if (tables == null) 135 return null; 136 137 String str = id.toString(); 138 int pos = str.lastIndexOf('.'); 139 String tableName = str.substring(0, pos); 140 Table t = findTable(tableName); 141 return t == null ? null : t.findColumn(id); 142 } 143 144 152 protected Table findTable(String tableName) { 153 Table t = (Table)tableCacheMap.get(tableName); 157 if (t != null) 158 return t; 159 160 String origTableName = tableName; 162 String schemaName = null; 163 int pos = tableName.indexOf('.'); 164 if (pos >= 0) { 165 schemaName = tableName.substring(0, pos); 166 tableName = tableName.substring(pos + 1); 167 } 168 169 if (!getReport().caseSensitiveDatabaseNames()) { 170 if (schemaName != null) schemaName = schemaName.toLowerCase(); 171 tableName = tableName.toLowerCase(); 172 } 173 174 if (schemaName != null) { 176 if ((t = findTableWithId(schemaName + '.' + tableName)) != null) { 177 tableCacheMap.put(origTableName, t); 178 return t; 179 } 180 } 181 182 if (name != null) { 185 String dbSchemaName = name; 186 if (!getReport().caseSensitiveDatabaseNames()) 187 dbSchemaName = dbSchemaName.toLowerCase(); 188 189 if (!dbSchemaName.equals(schemaName)) { 190 if ((t = findTableWithId(dbSchemaName + '.' + tableName)) != null) 191 { 192 tableCacheMap.put(origTableName, t); 193 return t; 194 } 195 } 196 } 197 198 if ((t = findTableWithId(tableName)) != null) { 200 tableCacheMap.put(origTableName, t); 201 return t; 202 } 203 204 return null; 205 } 206 207 215 protected Table findTableWithId(String id) { 216 boolean caseSensitive = getReport().caseSensitiveDatabaseNames(); 217 for (Iterator iter = tables.keySet().iterator(); iter.hasNext(); ) { 218 String key = (String )iter.next(); 219 if (key.equals(id) || (!caseSensitive && key.equalsIgnoreCase(id))) 220 return (Table)tables.get(key); 221 } 222 223 return null; 224 } 225 226 public Iterator tables() { 227 return tables.values().iterator(); 228 } 229 230 public Iterator tablesUsedInReport() { 231 return ((SQLQuery)query).getTablesUsed().iterator(); 232 } 233 234 public Iterator columns() { 235 return new ColumnIterator(tables.values().iterator()); 236 } 237 238 public DataCursor execute() throws SQLException { 239 return new ResultSetRow(conn, (SQLQuery)query); 240 } 241 242 public boolean storesLowerCaseIdentifiers() { 243 return storesLowerCaseIdentifiers; 244 } 245 246 public boolean storesUpperCaseIdentifiers() { 247 return storesUpperCaseIdentifiers; 248 } 249 250 255 public void initializeConnection() 256 throws ClassNotFoundException , InstantiationException , 257 IllegalAccessException , UserCancellationException 258 { 259 boolean ok = false; 263 while (!ok) { 264 if (!hasPassword) { 265 report.askForPassword(this); 267 hasPassword = true; 268 } 269 if (password == null) 270 throw new UserCancellationException(I18N.get("Database.cancelled")); 271 272 try { 273 if (connInfo == null || connInfo.length() == 0) 274 throw new IllegalArgumentException (I18N.get("Database.missing_conn_info")); 275 if (username == null || username.length() == 0) 276 throw new IllegalArgumentException (I18N.get("Database.missing_user_name")); 277 if (password == null) 278 throw new IllegalArgumentException (I18N.get("Database.null_password")); 279 280 Driver d = (Driver)Class.forName(driverClassName).newInstance(); 282 DriverManager.registerDriver(d); 283 284 conn = DriverManager.getConnection(connInfo, username, password); 286 connectionOwnedByMe = true; 287 288 ok = true; 289 } 290 catch (SQLException sqle) { ErrorHandler.error(sqle); 292 hasPassword = false; 293 report.setDatabasePassword(null); 294 } 295 } 296 } 297 298 303 public Connection getConnection() { return conn; } 304 305 319 public void reset(String driverClassName, String connInfo, String dbName, 320 String username, String password) 321 throws SQLException, ClassNotFoundException , InstantiationException , 322 IllegalAccessException , UserCancellationException 323 { 324 setDriverClassName(driverClassName); 325 setConnectionInfo(connInfo); 326 setName(dbName); 327 setUserName(username); 328 this.password = password; 329 hasPassword = true; 330 331 if (conn != null) { 332 if (connectionOwnedByMe) 333 conn.close(); 334 conn = null; 335 } 336 initializeConnection(); 337 loadAllTables(); 338 339 report.reloadColumns(); 340 } 341 342 347 protected void loadAllTables() throws SQLException { 348 tables = new TreeMap(); 349 tableCacheMap = new HashMap(); 350 schemaName = null; 351 352 DatabaseMetaData dbmd = getConnection().getMetaData(); 353 storesLowerCaseIdentifiers = dbmd.storesLowerCaseIdentifiers(); 354 storesUpperCaseIdentifiers = dbmd.storesUpperCaseIdentifiers(); 355 356 try { 357 loadTablesUsingSchemaNameAndTypes(dbmd, name, DB_OBJECT_TYPES); 359 } catch (SQLException e) {} 360 catch (NullPointerException npe) {} 361 362 try { 363 if (tables.isEmpty() && name != null) loadTablesUsingSchemaNameAndTypes(dbmd, name, null); 365 } catch (SQLException e) {} 366 catch (NullPointerException npe) {} 367 368 try { 369 if (tables.isEmpty()) loadTablesUsingSchemaNameAndTypes(dbmd, null, DB_OBJECT_TYPES); 371 } catch (SQLException e) {} 372 catch (NullPointerException npe) {} 373 374 if (tables.isEmpty()) loadTablesUsingSchemaNameAndTypes(dbmd, null, null); 378 } 379 380 388 protected void loadTablesUsingSchemaNameAndTypes(DatabaseMetaData dbmd, 389 String schema, 390 String [] objectTypes) 391 throws SQLException 392 { 393 ResultSet rset = dbmd.getTables(null, schema, "%", objectTypes); 394 if (rset == null) return; 395 396 boolean schemaNameFailed = false; while (rset.next()) { 398 String name = rset.getString("TABLE_NAME").trim(); 399 400 if (!schemaNameFailed) { 401 try { 402 schemaName = rset.getString("TABLE_SCHEM"); 403 } 404 catch (SQLException sqle) { 405 schemaNameFailed = true; 406 } 407 if (schemaName != null && schemaName.length() > 0) 408 name = schemaName.trim() + '.' + name; 409 } 410 411 SQLTable t = new SQLTable(this, name, dbmd); 412 tables.put(t.getId().toString(), t); 413 } 414 rset.close(); 415 } 416 417 422 public String getDriverClassName() { return driverClassName; } 423 424 429 protected void setDriverClassName(String newDriverClassName) { 430 driverClassName = newDriverClassName; 431 } 432 433 438 public String getConnectionInfo() { return connInfo; } 439 440 445 protected void setConnectionInfo(String newConnectionInfo) { 446 connInfo = newConnectionInfo; 447 } 448 449 454 public String getName() { return name; } 455 456 461 protected void setName(String newName) { name = newName; } 462 463 468 public String getUserName() { return username; } 469 470 475 public void setUserName(String newUserName) { username = newUserName; } 476 477 482 public String getPassword() { return hasPassword ? password : null; } 483 484 489 public void setPassword(String newPassword) { 490 password = newPassword; 491 hasPassword = true; 492 } 493 494 499 protected void doWriteXML(XMLWriter out) { 500 out.startElement("database"); 501 out.attr("driverClassName", driverClassName); 502 out.attr("connInfo", connInfo); 503 out.attr("name", name); 504 out.attr("username", username); 505 out.endElement(); 506 } 507 508 } 509 | Popular Tags |