1 17 18 package org.apache.catalina.session; 19 20 import org.apache.catalina.Container; 21 import org.apache.catalina.LifecycleException; 22 import org.apache.catalina.Loader; 23 import org.apache.catalina.Session; 24 import org.apache.catalina.Store; 25 import org.apache.catalina.util.CustomObjectInputStream; 26 import java.io.BufferedInputStream ; 27 import java.io.BufferedOutputStream ; 28 import java.io.ByteArrayInputStream ; 29 import java.io.ByteArrayOutputStream ; 30 import java.io.IOException ; 31 import java.io.InputStream ; 32 import java.io.ObjectInputStream ; 33 import java.io.ObjectOutputStream ; 34 import java.sql.Connection ; 35 import java.sql.Driver ; 36 import java.sql.PreparedStatement ; 37 import java.sql.ResultSet ; 38 import java.sql.SQLException ; 39 import java.util.ArrayList ; 40 import java.util.Properties ; 41 42 50 51 public class JDBCStore 52 extends StoreBase implements Store { 53 54 57 protected static String info = "JDBCStore/1.0"; 58 59 62 private String name = null; 63 64 67 protected static String storeName = "JDBCStore"; 68 69 72 protected String threadName = "JDBCStore"; 73 74 77 protected String connectionName = null; 78 79 80 83 protected String connectionPassword = null; 84 85 88 protected String connectionURL = null; 89 90 93 private Connection dbConnection = null; 94 95 98 protected Driver driver = null; 99 100 103 protected String driverName = null; 104 105 107 110 protected String sessionTable = "tomcat$sessions"; 111 112 115 protected String sessionAppCol = "app"; 116 117 120 protected String sessionIdCol = "id"; 121 122 125 protected String sessionDataCol = "data"; 126 127 130 protected String sessionValidCol = "valid"; 131 132 135 protected String sessionMaxInactiveCol = "maxinactive"; 136 137 140 protected String sessionLastAccessedCol = "lastaccess"; 141 142 144 147 protected PreparedStatement preparedSizeSql = null; 148 149 152 protected PreparedStatement preparedKeysSql = null; 153 154 157 protected PreparedStatement preparedSaveSql = null; 158 159 162 protected PreparedStatement preparedClearSql = null; 163 164 167 protected PreparedStatement preparedRemoveSql = null; 168 169 172 protected PreparedStatement preparedLoadSql = null; 173 174 176 179 public String getInfo() { 180 return (info); 181 } 182 183 186 public String getName() { 187 if (name == null) { 188 Container container = manager.getContainer(); 189 String contextName = container.getName(); 190 String hostName = ""; 191 String engineName = ""; 192 193 if (container.getParent() != null) { 194 Container host = container.getParent(); 195 hostName = host.getName(); 196 if (host.getParent() != null) { 197 engineName = host.getParent().getName(); 198 } 199 } 200 name = "/" + engineName + "/" + hostName + contextName; 201 } 202 return name; 203 } 204 205 208 public String getThreadName() { 209 return (threadName); 210 } 211 212 215 public String getStoreName() { 216 return (storeName); 217 } 218 219 224 public void setDriverName(String driverName) { 225 String oldDriverName = this.driverName; 226 this.driverName = driverName; 227 support.firePropertyChange("driverName", 228 oldDriverName, 229 this.driverName); 230 this.driverName = driverName; 231 } 232 233 236 public String getDriverName() { 237 return (this.driverName); 238 } 239 240 244 public String getConnectionName() { 245 return connectionName; 246 } 247 248 253 public void setConnectionName(String connectionName) { 254 this.connectionName = connectionName; 255 } 256 257 261 public String getConnectionPassword() { 262 return connectionPassword; 263 } 264 265 270 public void setConnectionPassword(String connectionPassword) { 271 this.connectionPassword = connectionPassword; 272 } 273 274 279 public void setConnectionURL(String connectionURL) { 280 String oldConnString = this.connectionURL; 281 this.connectionURL = connectionURL; 282 support.firePropertyChange("connectionURL", 283 oldConnString, 284 this.connectionURL); 285 } 286 287 290 public String getConnectionURL() { 291 return (this.connectionURL); 292 } 293 294 299 public void setSessionTable(String sessionTable) { 300 String oldSessionTable = this.sessionTable; 301 this.sessionTable = sessionTable; 302 support.firePropertyChange("sessionTable", 303 oldSessionTable, 304 this.sessionTable); 305 } 306 307 310 public String getSessionTable() { 311 return (this.sessionTable); 312 } 313 314 319 public void setSessionAppCol(String sessionAppCol) { 320 String oldSessionAppCol = this.sessionAppCol; 321 this.sessionAppCol = sessionAppCol; 322 support.firePropertyChange("sessionAppCol", 323 oldSessionAppCol, 324 this.sessionAppCol); 325 } 326 327 330 public String getSessionAppCol() { 331 return (this.sessionAppCol); 332 } 333 334 339 public void setSessionIdCol(String sessionIdCol) { 340 String oldSessionIdCol = this.sessionIdCol; 341 this.sessionIdCol = sessionIdCol; 342 support.firePropertyChange("sessionIdCol", 343 oldSessionIdCol, 344 this.sessionIdCol); 345 } 346 347 350 public String getSessionIdCol() { 351 return (this.sessionIdCol); 352 } 353 354 359 public void setSessionDataCol(String sessionDataCol) { 360 String oldSessionDataCol = this.sessionDataCol; 361 this.sessionDataCol = sessionDataCol; 362 support.firePropertyChange("sessionDataCol", 363 oldSessionDataCol, 364 this.sessionDataCol); 365 } 366 367 370 public String getSessionDataCol() { 371 return (this.sessionDataCol); 372 } 373 374 379 public void setSessionValidCol(String sessionValidCol) { 380 String oldSessionValidCol = this.sessionValidCol; 381 this.sessionValidCol = sessionValidCol; 382 support.firePropertyChange("sessionValidCol", 383 oldSessionValidCol, 384 this.sessionValidCol); 385 } 386 387 390 public String getSessionValidCol() { 391 return (this.sessionValidCol); 392 } 393 394 399 public void setSessionMaxInactiveCol(String sessionMaxInactiveCol) { 400 String oldSessionMaxInactiveCol = this.sessionMaxInactiveCol; 401 this.sessionMaxInactiveCol = sessionMaxInactiveCol; 402 support.firePropertyChange("sessionMaxInactiveCol", 403 oldSessionMaxInactiveCol, 404 this.sessionMaxInactiveCol); 405 } 406 407 410 public String getSessionMaxInactiveCol() { 411 return (this.sessionMaxInactiveCol); 412 } 413 414 419 public void setSessionLastAccessedCol(String sessionLastAccessedCol) { 420 String oldSessionLastAccessedCol = this.sessionLastAccessedCol; 421 this.sessionLastAccessedCol = sessionLastAccessedCol; 422 support.firePropertyChange("sessionLastAccessedCol", 423 oldSessionLastAccessedCol, 424 this.sessionLastAccessedCol); 425 } 426 427 430 public String getSessionLastAccessedCol() { 431 return (this.sessionLastAccessedCol); 432 } 433 434 436 443 public String [] keys() throws IOException { 444 ResultSet rst = null; 445 String keys[] = null; 446 synchronized (this) { 447 int numberOfTries = 2; 448 while (numberOfTries > 0) { 449 450 Connection _conn = getConnection(); 451 if (_conn == null) { 452 return (new String [0]); 453 } 454 try { 455 if (preparedKeysSql == null) { 456 String keysSql = "SELECT " + sessionIdCol + " FROM " 457 + sessionTable + " WHERE " + sessionAppCol 458 + " = ?"; 459 preparedKeysSql = _conn.prepareStatement(keysSql); 460 } 461 462 preparedKeysSql.setString(1, getName()); 463 rst = preparedKeysSql.executeQuery(); 464 ArrayList tmpkeys = new ArrayList (); 465 if (rst != null) { 466 while (rst.next()) { 467 tmpkeys.add(rst.getString(1)); 468 } 469 } 470 keys = (String []) tmpkeys.toArray(new String [tmpkeys.size()]); 471 numberOfTries = 0; 473 } catch (SQLException e) { 474 manager.getContainer().getLogger().error(sm.getString(getStoreName() + ".SQLException", e)); 475 keys = new String [0]; 476 if (dbConnection != null) 478 close(dbConnection); 479 } finally { 480 try { 481 if (rst != null) { 482 rst.close(); 483 } 484 } catch (SQLException e) { 485 ; 486 } 487 488 release(_conn); 489 } 490 numberOfTries--; 491 } 492 } 493 494 return (keys); 495 } 496 497 504 public int getSize() throws IOException { 505 int size = 0; 506 ResultSet rst = null; 507 508 synchronized (this) { 509 int numberOfTries = 2; 510 while (numberOfTries > 0) { 511 Connection _conn = getConnection(); 512 513 if (_conn == null) { 514 return (size); 515 } 516 517 try { 518 if (preparedSizeSql == null) { 519 String sizeSql = "SELECT COUNT(" + sessionIdCol 520 + ") FROM " + sessionTable + " WHERE " 521 + sessionAppCol + " = ?"; 522 preparedSizeSql = _conn.prepareStatement(sizeSql); 523 } 524 525 preparedSizeSql.setString(1, getName()); 526 rst = preparedSizeSql.executeQuery(); 527 if (rst.next()) { 528 size = rst.getInt(1); 529 } 530 numberOfTries = 0; 532 } catch (SQLException e) { 533 manager.getContainer().getLogger().error(sm.getString(getStoreName() + ".SQLException", e)); 534 if (dbConnection != null) 535 close(dbConnection); 536 } finally { 537 try { 538 if (rst != null) 539 rst.close(); 540 } catch (SQLException e) { 541 ; 542 } 543 544 release(_conn); 545 } 546 numberOfTries--; 547 } 548 } 549 return (size); 550 } 551 552 561 public Session load(String id) 562 throws ClassNotFoundException , IOException { 563 ResultSet rst = null; 564 StandardSession _session = null; 565 Loader loader = null; 566 ClassLoader classLoader = null; 567 ObjectInputStream ois = null; 568 BufferedInputStream bis = null; 569 Container container = manager.getContainer(); 570 571 synchronized (this) { 572 int numberOfTries = 2; 573 while (numberOfTries > 0) { 574 Connection _conn = getConnection(); 575 if (_conn == null) { 576 return (null); 577 } 578 579 try { 580 if (preparedLoadSql == null) { 581 String loadSql = "SELECT " + sessionIdCol + ", " 582 + sessionDataCol + " FROM " + sessionTable 583 + " WHERE " + sessionIdCol + " = ? AND " 584 + sessionAppCol + " = ?"; 585 preparedLoadSql = _conn.prepareStatement(loadSql); 586 } 587 588 preparedLoadSql.setString(1, id); 589 preparedLoadSql.setString(2, getName()); 590 rst = preparedLoadSql.executeQuery(); 591 if (rst.next()) { 592 bis = new BufferedInputStream (rst.getBinaryStream(2)); 593 594 if (container != null) { 595 loader = container.getLoader(); 596 } 597 if (loader != null) { 598 classLoader = loader.getClassLoader(); 599 } 600 if (classLoader != null) { 601 ois = new CustomObjectInputStream(bis, 602 classLoader); 603 } else { 604 ois = new ObjectInputStream(bis); 605 } 606 607 if (manager.getContainer().getLogger().isDebugEnabled()) { 608 manager.getContainer().getLogger().debug(sm.getString(getStoreName() + ".loading", 609 id, sessionTable)); 610 } 611 612 _session = (StandardSession) manager.createEmptySession(); 613 _session.readObjectData(ois); 614 _session.setManager(manager); 615 } else if (manager.getContainer().getLogger().isDebugEnabled()) { 616 manager.getContainer().getLogger().debug(getStoreName() + ": No persisted data object found"); 617 } 618 numberOfTries = 0; 620 } catch (SQLException e) { 621 manager.getContainer().getLogger().error(sm.getString(getStoreName() + ".SQLException", e)); 622 if (dbConnection != null) 623 close(dbConnection); 624 } finally { 625 try { 626 if (rst != null) { 627 rst.close(); 628 } 629 } catch (SQLException e) { 630 ; 631 } 632 if (ois != null) { 633 try { 634 ois.close(); 635 } catch (IOException e) { 636 ; 637 } 638 } 639 release(_conn); 640 } 641 numberOfTries--; 642 } 643 } 644 645 return (_session); 646 } 647 648 657 public void remove(String id) throws IOException { 658 659 synchronized (this) { 660 int numberOfTries = 2; 661 while (numberOfTries > 0) { 662 Connection _conn = getConnection(); 663 664 if (_conn == null) { 665 return; 666 } 667 668 try { 669 if (preparedRemoveSql == null) { 670 String removeSql = "DELETE FROM " + sessionTable 671 + " WHERE " + sessionIdCol + " = ? AND " 672 + sessionAppCol + " = ?"; 673 preparedRemoveSql = _conn.prepareStatement(removeSql); 674 } 675 676 preparedRemoveSql.setString(1, id); 677 preparedRemoveSql.setString(2, getName()); 678 preparedRemoveSql.execute(); 679 numberOfTries = 0; 681 } catch (SQLException e) { 682 manager.getContainer().getLogger().error(sm.getString(getStoreName() + ".SQLException", e)); 683 if (dbConnection != null) 684 close(dbConnection); 685 } finally { 686 release(_conn); 687 } 688 numberOfTries--; 689 } 690 } 691 692 if (manager.getContainer().getLogger().isDebugEnabled()) { 693 manager.getContainer().getLogger().debug(sm.getString(getStoreName() + ".removing", id, sessionTable)); 694 } 695 } 696 697 702 public void clear() throws IOException { 703 704 synchronized (this) { 705 int numberOfTries = 2; 706 while (numberOfTries > 0) { 707 Connection _conn = getConnection(); 708 if (_conn == null) { 709 return; 710 } 711 712 try { 713 if (preparedClearSql == null) { 714 String clearSql = "DELETE FROM " + sessionTable 715 + " WHERE " + sessionAppCol + " = ?"; 716 preparedClearSql = _conn.prepareStatement(clearSql); 717 } 718 719 preparedClearSql.setString(1, getName()); 720 preparedClearSql.execute(); 721 numberOfTries = 0; 723 } catch (SQLException e) { 724 manager.getContainer().getLogger().error(sm.getString(getStoreName() + ".SQLException", e)); 725 if (dbConnection != null) 726 close(dbConnection); 727 } finally { 728 release(_conn); 729 } 730 numberOfTries--; 731 } 732 } 733 } 734 735 741 public void save(Session session) throws IOException { 742 ObjectOutputStream oos = null; 743 ByteArrayOutputStream bos = null; 744 ByteArrayInputStream bis = null; 745 InputStream in = null; 746 747 synchronized (this) { 748 int numberOfTries = 2; 749 while (numberOfTries > 0) { 750 Connection _conn = getConnection(); 751 if (_conn == null) { 752 return; 753 } 754 755 remove(session.getIdInternal()); 759 760 try { 761 bos = new ByteArrayOutputStream (); 762 oos = new ObjectOutputStream (new BufferedOutputStream (bos)); 763 764 ((StandardSession) session).writeObjectData(oos); 765 oos.close(); 766 oos = null; 767 byte[] obs = bos.toByteArray(); 768 int size = obs.length; 769 bis = new ByteArrayInputStream (obs, 0, size); 770 in = new BufferedInputStream (bis, size); 771 772 if (preparedSaveSql == null) { 773 String saveSql = "INSERT INTO " + sessionTable + " (" 774 + sessionIdCol + ", " + sessionAppCol + ", " 775 + sessionDataCol + ", " + sessionValidCol 776 + ", " + sessionMaxInactiveCol + ", " 777 + sessionLastAccessedCol 778 + ") VALUES (?, ?, ?, ?, ?, ?)"; 779 preparedSaveSql = _conn.prepareStatement(saveSql); 780 } 781 782 preparedSaveSql.setString(1, session.getIdInternal()); 783 preparedSaveSql.setString(2, getName()); 784 preparedSaveSql.setBinaryStream(3, in, size); 785 preparedSaveSql.setString(4, session.isValid() ? "1" : "0"); 786 preparedSaveSql.setInt(5, session.getMaxInactiveInterval()); 787 preparedSaveSql.setLong(6, session.getLastAccessedTime()); 788 preparedSaveSql.execute(); 789 numberOfTries = 0; 791 } catch (SQLException e) { 792 manager.getContainer().getLogger().error(sm.getString(getStoreName() + ".SQLException", e)); 793 if (dbConnection != null) 794 close(dbConnection); 795 } catch (IOException e) { 796 ; 797 } finally { 798 if (oos != null) { 799 oos.close(); 800 } 801 if (bis != null) { 802 bis.close(); 803 } 804 if (in != null) { 805 in.close(); 806 } 807 808 release(_conn); 809 } 810 numberOfTries--; 811 } 812 } 813 814 if (manager.getContainer().getLogger().isDebugEnabled()) { 815 manager.getContainer().getLogger().debug(sm.getString(getStoreName() + ".saving", 816 session.getIdInternal(), sessionTable)); 817 } 818 } 819 820 822 829 protected Connection getConnection() { 830 try { 831 if (dbConnection == null || dbConnection.isClosed()) { 832 manager.getContainer().getLogger().info(sm.getString(getStoreName() + ".checkConnectionDBClosed")); 833 open(); 834 if (dbConnection == null || dbConnection.isClosed()) { 835 manager.getContainer().getLogger().info(sm.getString(getStoreName() + ".checkConnectionDBReOpenFail")); 836 } 837 } 838 } catch (SQLException ex) { 839 manager.getContainer().getLogger().error(sm.getString(getStoreName() + ".checkConnectionSQLException", 840 ex.toString())); 841 } 842 843 return dbConnection; 844 } 845 846 852 protected Connection open() throws SQLException { 853 854 if (dbConnection != null) 856 return (dbConnection); 857 858 if (driver == null) { 860 try { 861 Class clazz = Class.forName(driverName); 862 driver = (Driver ) clazz.newInstance(); 863 } catch (ClassNotFoundException ex) { 864 manager.getContainer().getLogger().error(sm.getString(getStoreName() + ".checkConnectionClassNotFoundException", 865 ex.toString())); 866 } catch (InstantiationException ex) { 867 manager.getContainer().getLogger().error(sm.getString(getStoreName() + ".checkConnectionClassNotFoundException", 868 ex.toString())); 869 } catch (IllegalAccessException ex) { 870 manager.getContainer().getLogger().error(sm.getString(getStoreName() + ".checkConnectionClassNotFoundException", 871 ex.toString())); 872 } 873 } 874 875 Properties props = new Properties (); 877 if (connectionName != null) 878 props.put("user", connectionName); 879 if (connectionPassword != null) 880 props.put("password", connectionPassword); 881 dbConnection = driver.connect(connectionURL, props); 882 dbConnection.setAutoCommit(true); 883 return (dbConnection); 884 885 } 886 887 892 protected void close(Connection dbConnection) { 893 894 if (dbConnection == null) 896 return; 897 898 try { 900 preparedSizeSql.close(); 901 } catch (Throwable f) { 902 ; 903 } 904 this.preparedSizeSql = null; 905 906 try { 907 preparedKeysSql.close(); 908 } catch (Throwable f) { 909 ; 910 } 911 this.preparedKeysSql = null; 912 913 try { 914 preparedSaveSql.close(); 915 } catch (Throwable f) { 916 ; 917 } 918 this.preparedSaveSql = null; 919 920 try { 921 preparedClearSql.close(); 922 } catch (Throwable f) { 923 ; 924 } 925 926 try { 927 preparedRemoveSql.close(); 928 } catch (Throwable f) { 929 ; 930 } 931 this.preparedRemoveSql = null; 932 933 try { 934 preparedLoadSql.close(); 935 } catch (Throwable f) { 936 ; 937 } 938 this.preparedLoadSql = null; 939 940 try { 942 dbConnection.close(); 943 } catch (SQLException e) { 944 manager.getContainer().getLogger().error(sm.getString(getStoreName() + ".close", e.toString())); } finally { 946 this.dbConnection = null; 947 } 948 949 } 950 951 957 protected void release(Connection conn) { 958 ; 959 } 960 961 964 public void start() throws LifecycleException { 965 super.start(); 966 967 this.dbConnection = getConnection(); 969 } 970 971 976 public void stop() throws LifecycleException { 977 super.stop(); 978 979 if (dbConnection != null) { 981 try { 982 dbConnection.commit(); 983 } catch (SQLException e) { 984 ; 985 } 986 close(dbConnection); 987 } 988 } 989 } 990 | Popular Tags |