0001 /*
0002 * AccessControllerImpl.java
0003 *
0004 * Copyright (c) 1995-2010, The University of Sheffield. See the file
0005 * COPYRIGHT.txt in the software or at http://gate.ac.uk/gate/COPYRIGHT.txt
0006 *
0007 * This file is part of GATE (see http://gate.ac.uk/), and is free
0008 * software, licenced under the GNU Library General Public License,
0009 * Version 2, June 1991 (in the distribution as file licence.html,
0010 * and also available at http://gate.ac.uk/gate/licence.html).
0011 *
0012 * Marin Dimitrov, 19/Sep/2001
0013 *
0014 * $Id: AccessControllerImpl.java 12006 2009-12-01 17:24:28Z thomas_heitz $
0015 */
0016
0017 package gate.security;
0018
0019 import java.sql.*;
0020 import java.util.*;
0021
0022 import junit.framework.Assert;
0023
0024 import gate.Gate;
0025 import gate.event.*;
0026 import gate.persist.DBHelper;
0027 import gate.persist.PersistenceException;
0028 import gate.util.MethodNotImplementedException;
0029
0030
0031 public class AccessControllerImpl
0032 implements AccessController, ObjectModificationListener {
0033
0034 public static final int DEFAULT_SESSION_TIMEOUT_MIN = 4*60;
0035
0036 public static final int LOGIN_OK = 1;
0037 public static final int LOGIN_FAILED = 2;
0038
0039 private static long MY_VERY_SECRET_CONSTANT;
0040 private static final int RANDOM_MAX = 1024;
0041
0042 private HashMap sessions;
0043 private HashMap sessionLastUsed;
0044 private HashMap sessionTimeouts;
0045
0046 private Connection jdbcConn;
0047 private String jdbcURL;
0048 private String jdbcSchema;
0049 protected int dbType;
0050
0051 private HashMap usersByID;
0052 private HashMap usersByName;
0053
0054 private HashMap groupsByID;
0055 private HashMap groupsByName;
0056
0057 private static Random r;
0058 private boolean isPooled;
0059
0060 private int refCnt;
0061
0062 /** --- */
0063 private Vector omModificationListeners;
0064 /** --- */
0065 private Vector omCreationListeners;
0066 /** --- */
0067 private Vector omDeletionListeners;
0068
0069
0070 static {
0071 r = new Random();
0072 MY_VERY_SECRET_CONSTANT = r.nextInt(RANDOM_MAX) * r.nextInt(RANDOM_MAX)
0073 + Math.round(Math.PI * Math.E);
0074 }
0075
0076 /** --- */
0077 public AccessControllerImpl(String jdbcURL) {
0078
0079 Assert.assertNotNull(jdbcURL);
0080
0081 this.refCnt = 0;
0082 this.jdbcURL = jdbcURL;
0083 this.jdbcSchema = DBHelper.getSchemaPrefix(this.jdbcURL);
0084 this.dbType = DBHelper.getDatabaseType(this.jdbcURL);
0085
0086 Assert.assertNotNull(this.jdbcSchema);
0087 Assert.assertTrue(this.dbType == DBHelper.ORACLE_DB ||
0088 this.dbType == DBHelper.POSTGRES_DB);
0089
0090 sessions = new HashMap();
0091 sessionLastUsed = new HashMap();
0092 sessionTimeouts = new HashMap();
0093
0094 usersByID = new HashMap();
0095 usersByName= new HashMap();
0096
0097 groupsByID = new HashMap();
0098 groupsByName = new HashMap();
0099
0100 this.omModificationListeners = new Vector();
0101 this.omCreationListeners = new Vector();
0102 this.omDeletionListeners = new Vector();
0103 }
0104
0105 /** --- */
0106 public void open()
0107 throws PersistenceException{
0108
0109 synchronized(this) {
0110 if (refCnt++ == 0) {
0111 //open connection
0112 try {
0113 //1. get connection to the database
0114 jdbcConn = DBHelper.connect(this.jdbcURL);
0115
0116 Assert.assertNotNull(jdbcConn);
0117
0118 //2. initialize group/user collections
0119 //init, i.e. read users and groups from DB
0120 init();
0121 }
0122 catch(SQLException sqle) {
0123 throw new PersistenceException("could not get DB connection ["+ sqle.getMessage() +"]");
0124 }
0125 catch(ClassNotFoundException clse) {
0126 throw new PersistenceException("cannot locate JDBC driver ["+ clse.getMessage() +"]");
0127 }
0128 }
0129 }
0130
0131
0132 }
0133
0134 /** --- */
0135 public void close()
0136 throws PersistenceException{
0137
0138 if (--this.refCnt == 0) {
0139
0140 //0. Invalidate all sessions
0141 this.sessions.clear();
0142 this.sessionLastUsed.clear();
0143 this.sessionTimeouts.clear();
0144
0145 //1. deregister self as listener for groups
0146 Set groupMappings = this.groupsByName.entrySet();
0147 Iterator itGroups = groupMappings.iterator();
0148
0149 while (itGroups.hasNext()) {
0150 Map.Entry mapEntry = (Map.Entry)itGroups.next();
0151 GroupImpl grp = (GroupImpl)mapEntry.getValue();
0152 grp.unregisterObjectModificationListener(this,
0153 ObjectModificationEvent.OBJECT_MODIFIED);
0154 }
0155
0156 //1.1. deregister self as listener for users
0157 Set userMappings = this.usersByName.entrySet();
0158 Iterator itUsers = userMappings.iterator();
0159
0160 while (itUsers.hasNext()) {
0161 Map.Entry mapEntry = (Map.Entry)itUsers.next();
0162 UserImpl usr = (UserImpl)mapEntry.getValue();
0163 usr.unregisterObjectModificationListener(this,
0164 ObjectModificationEvent.OBJECT_MODIFIED);
0165 }
0166
0167 //1.2 release all listeners registered for this object
0168 this.omCreationListeners.removeAllElements();
0169 this.omDeletionListeners.removeAllElements();
0170 this.omModificationListeners.removeAllElements();
0171
0172 //2. delete all groups/users collections
0173 this.groupsByID.clear();
0174 this.groupsByName.clear();
0175 this.usersByID.clear();
0176 this.groupsByName.clear();
0177
0178 //3.close connection (if not pooled)
0179 try {
0180 if (false == this.isPooled) {
0181 this.jdbcConn.close();
0182 }
0183 }
0184 catch(SQLException sqle) {
0185 throw new PersistenceException("can't close connection to DB:["+
0186 sqle.getMessage()+"]");
0187 }
0188 }
0189 }
0190
0191 /** --- */
0192 public Group findGroup(String name)
0193 throws PersistenceException,SecurityException{
0194
0195 Group grp = (Group)this.groupsByName.get(name);
0196
0197 if (null == grp) {
0198 throw new SecurityException("No such group");
0199 }
0200
0201 return grp;
0202 }
0203
0204 /** --- */
0205 public Group findGroup(Long id)
0206 throws PersistenceException,SecurityException {
0207
0208 Group grp = (Group)this.groupsByID.get(id);
0209
0210 if (null == grp) {
0211 throw new SecurityException("No such group");
0212 }
0213
0214 return grp;
0215 }
0216
0217 /** --- */
0218 public User findUser(String name)
0219 throws PersistenceException,SecurityException {
0220
0221 User usr = (User)this.usersByName.get(name);
0222
0223 if (null == usr) {
0224 throw new SecurityException("No such user (" + name + ")");
0225 }
0226
0227 return usr;
0228 }
0229
0230 /** --- */
0231 public User findUser(Long id)
0232 throws PersistenceException,SecurityException {
0233
0234 User usr = (User)this.usersByID.get(id);
0235
0236 if (null == usr) {
0237 throw new SecurityException("No such user");
0238 }
0239
0240 return usr;
0241 }
0242
0243 /** --- */
0244 public Session findSession(Long id)
0245 throws SecurityException {
0246
0247 Session s = (Session)this.sessions.get(id);
0248
0249 if (null==s) {
0250 throw new SecurityException("No such session ID!");
0251 }
0252
0253 return s;
0254 }
0255
0256 /** --- */
0257 public Group createGroup(String name,Session s)
0258 throws PersistenceException, SecurityException {
0259
0260 Assert.assertNotNull(name);
0261
0262 //-1. check session
0263 if (false == isValidSession(s)) {
0264 throw new SecurityException("invalid session supplied");
0265 }
0266
0267 //0. check privileges
0268 if (false == s.isPrivilegedSession()) {
0269 throw new SecurityException("insufficient privileges");
0270 }
0271
0272
0273 //1. create group in DB
0274 CallableStatement stmt = null;
0275 PreparedStatement pstmt = null;
0276 ResultSet rs = null;
0277 Long new_id;
0278
0279 //Oracle / Postgres ?
0280
0281 if (this.dbType == DBHelper.ORACLE_DB) {
0282
0283 try {
0284 stmt = this.jdbcConn.prepareCall(
0285 "{ call "+Gate.DB_OWNER+".security.create_group(?,?)} ");
0286 stmt.setString(1,name);
0287 //numbers generated from Oracle sequences are BIGINT
0288 stmt.registerOutParameter(2,java.sql.Types.BIGINT);
0289 stmt.execute();
0290 new_id = new Long(stmt.getLong(2));
0291 }
0292 catch(SQLException sqle) {
0293
0294 //check for more specifi exceptions
0295 switch(sqle.getErrorCode()) {
0296
0297 case DBHelper.X_ORACLE_DUPLICATE_GROUP_NAME:
0298 throw new PersistenceException(
0299 "can't create a group in DB, name is not unique: ["
0300 + sqle.getMessage()+"]");
0301
0302 default:
0303 throw new PersistenceException(
0304 "can't create a group in DB: ["+ sqle.getMessage()+"]");
0305 }
0306 }
0307 finally {
0308 DBHelper.cleanup(stmt);
0309 }
0310 }
0311 else if (this.dbType == DBHelper.POSTGRES_DB) {
0312 try {
0313 String sql = "select security_create_group(?) ";
0314 pstmt = this.jdbcConn.prepareStatement(sql);
0315 pstmt.setString(1,name);
0316 pstmt.execute();
0317 rs = pstmt.getResultSet();
0318
0319 if (false == rs.next()) {
0320 throw new PersistenceException("empty resultset");
0321 }
0322
0323 new_id = new Long(rs.getLong(1));
0324 }
0325 catch(SQLException sqle) {
0326
0327 //check for more specifi exceptions
0328 switch(sqle.getErrorCode()) {
0329
0330 case DBHelper.X_ORACLE_DUPLICATE_GROUP_NAME:
0331 throw new PersistenceException(
0332 "can't create a group in DB, name is not unique: ["
0333 + sqle.getMessage()+"]");
0334
0335 default:
0336 throw new PersistenceException(
0337 "can't create a group in DB: ["+ sqle.getMessage()+"]");
0338 }
0339 }
0340 finally {
0341 DBHelper.cleanup(rs);
0342 DBHelper.cleanup(pstmt);
0343 }
0344
0345 }
0346 else {
0347 throw new IllegalArgumentException();
0348 }
0349
0350 //2. create GroupImpl for the new group and
0351 // users list is empty
0352 GroupImpl grp = new GroupImpl(new_id,name,new Vector(),this,this.jdbcConn);
0353
0354 //3. register as objectModification listener for this group
0355 //we care only about name changes
0356 grp.registerObjectModificationListener(this,ObjectModificationEvent.OBJECT_MODIFIED);
0357
0358 //4.put in collections
0359 this.groupsByID.put(new_id,grp);
0360 this.groupsByName.put(name,grp);
0361
0362 return grp;
0363 }
0364
0365 /** --- */
0366 public void deleteGroup(Long id, Session s)
0367 throws PersistenceException,SecurityException {
0368
0369 Group grp = (Group)this.groupsByID.get(id);
0370 if (null == grp) {
0371 throw new SecurityException("incorrect group id supplied ( id = ["+id+"])");
0372 }
0373
0374 //delegate
0375 deleteGroup(grp,s);
0376 }
0377
0378 /** --- */
0379 public void deleteGroup(Group grp, Session s)
0380 throws PersistenceException,SecurityException {
0381
0382 //1. check session
0383 if (false == isValidSession(s)) {
0384 throw new SecurityException("invalid session supplied");
0385 }
0386
0387 //2. check privileges
0388 if (false == s.isPrivilegedSession()) {
0389 throw new SecurityException("insufficient privileges");
0390 }
0391
0392 //3. delete in DB
0393 CallableStatement stmt = null;
0394 PreparedStatement pstmt = null;
0395
0396 //Oracle /Postgres ?
0397 if (this.dbType == DBHelper.ORACLE_DB) {
0398
0399 try {
0400 stmt = this.jdbcConn.prepareCall(
0401 "{ call "+Gate.DB_OWNER+".security.delete_group(?) } ");
0402 stmt.setLong(1,grp.getID().longValue());
0403 stmt.execute();
0404 }
0405 catch(SQLException sqle) {
0406 //check for more specific exceptions
0407 switch(sqle.getErrorCode()) {
0408
0409 case DBHelper.X_ORACLE_GROUP_OWNS_RESOURCES:
0410 throw new PersistenceException(
0411 "can't delete a group from DB, the group owns LR(s): ["
0412 + sqle.getMessage()+"]");
0413
0414 default:
0415 throw new PersistenceException(
0416 "can't delete a group from DB: ["+ sqle.getMessage()+"]");
0417 }
0418 }
0419 finally {
0420 DBHelper.cleanup(stmt);
0421 }
0422 }
0423
0424 else if (this.dbType == DBHelper.POSTGRES_DB) {
0425
0426 try {
0427 String sql = "select security_delete_group(?)";
0428 pstmt = this.jdbcConn.prepareStatement(sql);
0429 pstmt.setLong(1,grp.getID().longValue());
0430 pstmt.execute();
0431 }
0432 catch(SQLException sqle) {
0433 //check for more specific exceptions
0434 switch(sqle.getErrorCode()) {
0435
0436 case DBHelper.X_ORACLE_GROUP_OWNS_RESOURCES:
0437 throw new PersistenceException(
0438 "can't delete a group from DB, the group owns LR(s): ["
0439 + sqle.getMessage()+"]");
0440
0441 default:
0442 throw new PersistenceException(
0443 "can't delete a group from DB: ["+ sqle.getMessage()+"]");
0444 }
0445 }
0446 finally {
0447 DBHelper.cleanup(pstmt);
0448 }
0449
0450 }
0451 else {
0452 throw new IllegalArgumentException();
0453 }
0454
0455
0456 //4. delete from collections
0457 this.groupsByID.remove(grp.getID());
0458 this.groupsByName.remove(grp.getName());
0459
0460 //5. notify all other listeners
0461 //this one is tricky - sent OBJECT_DELETED event to all who care
0462 //but note that the SOURCE is not us but the object being deleted
0463 ObjectModificationEvent e = new ObjectModificationEvent(
0464 grp,
0465 ObjectModificationEvent.OBJECT_DELETED,
0466 0);
0467
0468 fireObjectDeletedEvent(e);
0469
0470 //6. this one is tricky: invalidate all sessions
0471 //that are for user logged in as members of this group
0472 Set sessionMappings = this.sessions.entrySet();
0473 Iterator itSessions = sessionMappings.iterator();
0474
0475 //6.1 to avoid ConcurrentModificationException store the sessions
0476 //found in a temp vector
0477 Vector sessionsToDelete = new Vector();
0478 while (itSessions.hasNext()) {
0479 Map.Entry mapEntry = (Map.Entry)itSessions.next();
0480 SessionImpl ses = (SessionImpl)mapEntry.getValue();
0481 if (ses.getGroup().equals(grp)) {
0482 //logout(ses); --> this will cause ConcurrentModificationException
0483 sessionsToDelete.add(ses);
0484 }
0485 }
0486 //6.2 now delete sessions
0487 for (int i=0; i< sessionsToDelete.size(); i++) {
0488 Session ses = (Session)sessionsToDelete.elementAt(i);
0489 logout(ses);
0490 }
0491
0492 }
0493
0494 /** --- */
0495 public User createUser(String name, String passwd,Session s)
0496 throws PersistenceException,SecurityException {
0497
0498 Assert.assertNotNull(name);
0499
0500 //-1. check session
0501 if (false == isValidSession(s)) {
0502 throw new SecurityException("invalid session supplied");
0503 }
0504
0505 //0. check privileges
0506 if (false == s.isPrivilegedSession()) {
0507 throw new SecurityException("insufficient privileges");
0508 }
0509
0510 //1. create user in DB
0511 CallableStatement stmt = null;
0512 PreparedStatement pstmt = null;
0513 ResultSet rs = null;
0514
0515 Long new_id;
0516
0517 if (this.dbType == DBHelper.ORACLE_DB) {
0518
0519 try {
0520 stmt = this.jdbcConn.prepareCall(
0521 "{ call "+Gate.DB_OWNER+".security.create_user(?,?,?)} ");
0522 stmt.setString(1,name);
0523 stmt.setString(2,passwd);
0524 //numbers generated from Oracle sequences are BIGINT
0525 stmt.registerOutParameter(3,java.sql.Types.BIGINT);
0526 stmt.execute();
0527 new_id = new Long(stmt.getLong(3));
0528 }
0529 catch(SQLException sqle) {
0530 //check for more specific exceptions
0531 switch(sqle.getErrorCode()) {
0532
0533 case DBHelper.X_ORACLE_DUPLICATE_USER_NAME:
0534 throw new PersistenceException(
0535 "can't create a user in DB, name is not unique: ["
0536 + sqle.getMessage()+"]");
0537 default:
0538 throw new PersistenceException(
0539 "can't create a user in DB: ["+ sqle.getMessage()+"]");
0540 }
0541 }
0542 finally {
0543 DBHelper.cleanup(stmt);
0544 }
0545 }
0546
0547 else if (this.dbType == DBHelper.POSTGRES_DB) {
0548
0549 try {
0550 String sql = "select security_create_user(?,?) ";
0551 pstmt = this.jdbcConn.prepareStatement(sql);
0552 pstmt.setString(1,name);
0553 pstmt.setString(2,passwd);
0554 pstmt.execute();
0555 rs = pstmt.getResultSet();
0556
0557 if (false == rs.next()) {
0558 throw new PersistenceException("empty resultset");
0559 }
0560
0561 new_id = new Long(rs.getLong(1));
0562 }
0563 catch(SQLException sqle) {
0564 //check for more specific exceptions
0565 switch(sqle.getErrorCode()) {
0566
0567 case DBHelper.X_ORACLE_DUPLICATE_USER_NAME:
0568 throw new PersistenceException(
0569 "can't create a user in DB, name is not unique: ["
0570 + sqle.getMessage()+"]");
0571 default:
0572 throw new PersistenceException(
0573 "can't create a user in DB: ["+ sqle.getMessage()+"]");
0574 }
0575 }
0576 finally {
0577 DBHelper.cleanup(rs);
0578 DBHelper.cleanup(pstmt);
0579 }
0580
0581 }
0582
0583 else {
0584 throw new IllegalArgumentException();
0585 }
0586
0587 //2. create UserImpl for the new user
0588 // groups list is empty
0589 UserImpl usr = new UserImpl(new_id,name,new Vector(),this,this.jdbcConn);
0590
0591 //3. register as objectModification listener for this user
0592 //we care only about user changing name
0593 usr.registerObjectModificationListener(this,ObjectModificationEvent.OBJECT_MODIFIED);
0594
0595 //4. put in collections
0596 this.usersByID.put(new_id,usr);
0597 this.usersByName.put(name,usr);
0598
0599 return usr;
0600 }
0601
0602 /** --- */
0603 public void deleteUser(User usr, Session s)
0604 throws PersistenceException,SecurityException {
0605
0606 //1. check session
0607 if (false == isValidSession(s)) {
0608 throw new SecurityException("invalid session supplied");
0609 }
0610
0611 //2. check privileges
0612 if (false == s.isPrivilegedSession()) {
0613 throw new SecurityException("insufficient privileges");
0614 }
0615
0616 //3. delete in DB
0617 CallableStatement cstmt = null;
0618 PreparedStatement pstmt = null;
0619
0620 if (this.dbType == DBHelper.ORACLE_DB) {
0621
0622 try {
0623 cstmt = this.jdbcConn.prepareCall(
0624 "{ call "+Gate.DB_OWNER+".security.delete_user(?) } ");
0625 cstmt.setLong(1,usr.getID().longValue());
0626 cstmt.execute();
0627 }
0628 catch(SQLException sqle) {
0629 switch(sqle.getErrorCode()) {
0630
0631 case DBHelper.X_ORACLE_USER_OWNS_RESOURCES:
0632 throw new PersistenceException(
0633 "can't delete user from DB, the user owns LR(s): ["
0634 + sqle.getMessage()+"]");
0635 default:
0636 throw new PersistenceException(
0637 "can't delete user from DB: ["+ sqle.getMessage()+"]");
0638 }
0639 }
0640 finally {
0641 DBHelper.cleanup(cstmt);
0642 }
0643 }
0644
0645 else if (this.dbType == DBHelper.POSTGRES_DB) {
0646
0647 try {
0648 String sql = "select security_delete_user(?) ";
0649 pstmt = this.jdbcConn.prepareStatement(sql);
0650 pstmt.setLong(1,usr.getID().longValue());
0651 pstmt.execute();
0652 }
0653 catch(SQLException sqle) {
0654 switch(sqle.getErrorCode()) {
0655
0656 case DBHelper.X_ORACLE_USER_OWNS_RESOURCES:
0657 throw new PersistenceException(
0658 "can't delete user from DB, the user owns LR(s): ["
0659 + sqle.getMessage()+"]");
0660 default:
0661 throw new PersistenceException(
0662 "can't delete user from DB: ["+ sqle.getMessage()+"]");
0663 }
0664 }
0665 finally {
0666 DBHelper.cleanup(pstmt);
0667 }
0668
0669 }
0670
0671 else {
0672 throw new IllegalArgumentException();
0673 }
0674
0675
0676 //4. delete from collections
0677 this.usersByID.remove(usr.getID());
0678 this.usersByName.remove(usr.getName());
0679
0680 //6. notify all other listeners
0681 //this one is tricky - sent OBJECT_DELETED event to all who care
0682 //but note that the SOURCE is not us but the object being deleted
0683 ObjectModificationEvent e = new ObjectModificationEvent(
0684 usr,
0685 ObjectModificationEvent.OBJECT_DELETED,
0686 0);
0687
0688 fireObjectDeletedEvent(e);
0689
0690 //7. this one is tricky: invalidate all sessions for the user
0691 Set sessionMappings = this.sessions.entrySet();
0692 Iterator itSessions = sessionMappings.iterator();
0693
0694 //7.1 to avoid ConcurrentModificationException store the sessions
0695 //found in a temp vector
0696 Vector sessionsToDelete = new Vector();
0697 while (itSessions.hasNext()) {
0698 Map.Entry mapEntry = (Map.Entry)itSessions.next();
0699 SessionImpl ses = (SessionImpl)mapEntry.getValue();
0700 if (ses.getUser().equals(usr)) {
0701 //logout(ses); --> this will cause ConcurrentModificationException
0702 sessionsToDelete.add(ses);
0703 }
0704 }
0705 //7.2 now delete sessions
0706 for (int i=0; i< sessionsToDelete.size(); i++) {
0707 Session ses = (Session)sessionsToDelete.elementAt(i);
0708 logout(ses);
0709 }
0710
0711 }
0712
0713
0714 /** --- */
0715 public void deleteUser(Long id, Session s)
0716 throws PersistenceException,SecurityException {
0717
0718 User usr = (User)usersByID.get(id);
0719 if (null == usr) {
0720 throw new SecurityException("incorrect user id supplied ( id = ["+id+"])");
0721 }
0722
0723 //delegate
0724 deleteUser(usr,s);
0725 }
0726
0727 /** --- */
0728 public Session login(String usr_name, String passwd,Long prefGroupID)
0729 throws PersistenceException,SecurityException {
0730
0731 //1. check the user locally
0732 User usr = (User)this.usersByName.get(usr_name);
0733 if (null == usr) {
0734 throw new SecurityException("no such user (username=["+usr_name+"])");
0735 }
0736
0737 //2. check group localy
0738 Group grp = (Group)this.groupsByID.get(prefGroupID);
0739 if (null == grp) {
0740 throw new SecurityException("no such group (id=["+prefGroupID+"])");
0741 }
0742
0743 //2. check user/pass in DB
0744 CallableStatement cstmt = null;
0745 PreparedStatement pstmt = null;
0746 ResultSet rs = null;
0747
0748 boolean isPrivilegedUser = false;
0749
0750 if (this.dbType == DBHelper.ORACLE_DB) {
0751
0752 try {
0753 cstmt = this.jdbcConn.prepareCall(
0754 "{ call "+Gate.DB_OWNER+".security.login(?,?,?,?)} ");
0755 cstmt.setString(1,usr_name);
0756 cstmt.setString(2,passwd);
0757 cstmt.setLong(3,prefGroupID.longValue());
0758 cstmt.registerOutParameter(4,java.sql.Types.NUMERIC);
0759 cstmt.execute();
0760 isPrivilegedUser = (cstmt.getInt(4) == DBHelper.FALSE ? false : true );
0761 }
0762 catch(SQLException sqle) {
0763 switch(sqle.getErrorCode())
0764 {
0765 case DBHelper.X_ORACLE_INVALID_USER_NAME :
0766 throw new SecurityException("Login failed: incorrect user");
0767 case DBHelper.X_ORACLE_INVALID_USER_PASS :
0768 throw new SecurityException("Login failed: incorrect password");
0769 case DBHelper.X_ORACLE_INVALID_USER_GROUP :
0770 throw new SecurityException("Login failed: incorrect group");
0771 default:
0772 throw new PersistenceException("can't login user, DB error is: ["+
0773 sqle.getMessage()+"]");
0774 }
0775 }
0776 finally {
0777 DBHelper.cleanup(cstmt);
0778 }
0779 }
0780
0781 else if (this.dbType == DBHelper.POSTGRES_DB) {
0782
0783 try {
0784 String sql = "select security_login(?,?,?) ";
0785 pstmt = this.jdbcConn.prepareStatement(sql);
0786 pstmt.setString(1,usr_name);
0787 pstmt.setString(2,passwd);
0788 pstmt.setLong(3,prefGroupID.longValue());
0789 pstmt.execute();
0790 rs = pstmt.getResultSet();
0791
0792 if (false == rs.next()) {
0793 throw new PersistenceException("empty resultset");
0794 }
0795
0796 isPrivilegedUser = rs.getBoolean(1);
0797 }
0798 catch(SQLException sqle) {
0799 switch(sqle.getErrorCode())
0800 {
0801 case DBHelper.X_ORACLE_INVALID_USER_NAME :
0802 throw new SecurityException("Login failed: incorrect user");
0803 case DBHelper.X_ORACLE_INVALID_USER_PASS :
0804 throw new SecurityException("Login failed: incorrect password");
0805 case DBHelper.X_ORACLE_INVALID_USER_GROUP :
0806 throw new SecurityException("Login failed: incorrect group");
0807 default:
0808 throw new PersistenceException("can't login user, DB error is: ["+
0809 sqle.getMessage()+"]");
0810 }
0811 }
0812 finally {
0813 DBHelper.cleanup(rs);
0814 DBHelper.cleanup(pstmt);
0815 }
0816 }
0817
0818 else {
0819 throw new IllegalArgumentException();
0820 }
0821
0822 //3. create a Session and set User/Group
0823 Long sessionID = createSessionID();
0824 while (this.sessions.containsKey(sessionID)) {
0825 sessionID = createSessionID();
0826 }
0827
0828 SessionImpl s = new SessionImpl(sessionID,
0829 usr,
0830 grp,
0831 DEFAULT_SESSION_TIMEOUT_MIN,
0832 isPrivilegedUser);
0833
0834 //4. add session to session collections
0835 this.sessions.put(s.getID(),s);
0836
0837 //5. set the session timeouts and keep alives
0838 this.sessionTimeouts.put(sessionID,new Long(DEFAULT_SESSION_TIMEOUT_MIN));
0839 touchSession(s); //this one changes the keepAlive time
0840
0841 return s;
0842 }
0843
0844 /** --- */
0845 public void logout(Session s)
0846 throws SecurityException {
0847
0848 Assert.assertNotNull(s);
0849 Long SID = s.getID();
0850
0851 //1.sessions
0852 Session removedSession = (Session)this.sessions.remove(SID);
0853 Assert.assertNotNull(removedSession);
0854
0855 //2. keep alives
0856 Object lastUsed = this.sessionLastUsed.remove(SID);
0857 Assert.assertNotNull(lastUsed);
0858
0859 //3. timeouts
0860 Object timeout = this.sessionTimeouts.remove(SID);
0861 Assert.assertNotNull(timeout);
0862 }
0863
0864 /** --- */
0865 public void setSessionTimeout(Session s, int timeoutMins)
0866 throws SecurityException {
0867
0868 this.sessionTimeouts.put(s.getID(),new Long(timeoutMins));
0869 }
0870
0871 /** --- */
0872 public boolean isValidSession(Session s) {
0873
0874 //1. do we have such session?
0875 if (false == this.sessions.containsKey(s.getID())) {
0876 return false;
0877 }
0878
0879 //2. has it expired meanwhile?
0880 Assert.assertNotNull(this.sessionLastUsed.get(s.getID()));
0881
0882 long lastUsedMS = ((Long)this.sessionLastUsed.get(s.getID())).longValue();
0883 long sessTimeoutMin = ((Long)this.sessionTimeouts.get(s.getID())).longValue();
0884 long currTimeMS = System.currentTimeMillis();
0885 //timeout is in minutes
0886 long lastUsedMin = (currTimeMS-lastUsedMS)/(1000*60);
0887
0888 if (lastUsedMin > sessTimeoutMin) {
0889 //oops, session expired
0890 //invalidate it and fail
0891 try {
0892 logout(s);
0893 }
0894 catch(SecurityException se) {
0895 //well, this can happen only if logout() was called together
0896 //with isValidSesion() but the possibility it too low to care
0897 //and synchronize access
0898 ;
0899 }
0900
0901 return false;
0902 }
0903
0904 //everything ok
0905 //touch session
0906 touchSession(s);
0907
0908 return true;
0909 }
0910
0911 /** -- */
0912 public List listGroups()
0913 throws PersistenceException {
0914
0915 //1. read all groups from DB
0916 Statement stmt = null;
0917 ResultSet rs = null;
0918 String sql;
0919 Vector result = new Vector();
0920
0921 try {
0922 stmt = this.jdbcConn.createStatement();
0923
0924 //1.1 read groups
0925 sql = " SELECT grp_name "+
0926 " FROM "+this.jdbcSchema+"t_group "+
0927 " ORDER BY grp_name ASC";
0928 rs = stmt.executeQuery(sql);
0929
0930 while (rs.next()) {
0931 //access by index is faster
0932 //first column index is 1
0933 String grp_name = rs.getString(1);
0934 result.add(grp_name);
0935 }
0936
0937 return result;
0938 }
0939 catch (SQLException sqle) {
0940 throw new PersistenceException("cannot read groups from DB :["+
0941 sqle.getMessage() +"]");
0942 }
0943 finally {
0944 DBHelper.cleanup(rs);
0945 DBHelper.cleanup(stmt);
0946 }
0947 }
0948
0949 /** -- */
0950 public List listUsers()
0951 throws PersistenceException {
0952
0953 //1. read all users from DB
0954 Statement stmt = null;
0955 ResultSet rs = null;
0956 String sql;
0957 Vector result = new Vector();
0958
0959 try {
0960 stmt = this.jdbcConn.createStatement();
0961
0962 //1.1 read groups
0963 sql = " SELECT usr_login "+
0964 " FROM "+this.jdbcSchema+"t_user "+
0965 " ORDER BY usr_login DESC";
0966 rs = stmt.executeQuery(sql);
0967
0968 while (rs.next()) {
0969 //access by index is faster
0970 //first column index is 1
0971 String usr_name = rs.getString(1);
0972 result.add(usr_name);
0973 }
0974
0975 return result;
0976 }
0977 catch (SQLException sqle) {
0978 throw new PersistenceException("cannot read groups from DB :["+
0979 sqle.getMessage() +"]");
0980 }
0981 finally {
0982 DBHelper.cleanup(rs);
0983 DBHelper.cleanup(stmt);
0984 }
0985 }
0986
0987
0988
0989 /* private methods */
0990
0991 private void touchSession(Session s) {
0992
0993 this.sessionLastUsed.put(s.getID(), new Long(System.currentTimeMillis()));
0994 }
0995
0996
0997 private Long createSessionID() {
0998
0999 //need a hint?
1000 return new Long(((System.currentTimeMillis() << 16) >> 16)*
1001 (r.nextInt(RANDOM_MAX))*
1002 Runtime.getRuntime().freeMemory()*
1003 MY_VERY_SECRET_CONSTANT);
1004 }
1005
1006
1007 private boolean canDeleteGroup(Group grp)
1008 throws PersistenceException, SecurityException{
1009
1010 //1. check group localy
1011 if (false == this.groupsByID.containsValue(grp)) {
1012 throw new SecurityException("no such group (id=["+grp.getID()+"])");
1013 }
1014
1015 //2. check DB
1016 CallableStatement stmt = null;
1017 PreparedStatement pstmt = null;
1018 ResultSet rs = null;
1019
1020 if (this.dbType == DBHelper.ORACLE_DB) {
1021
1022 try {
1023 stmt = this.jdbcConn.prepareCall(
1024 "{ ? = call "+Gate.DB_OWNER+".security.can_delete_group(?) }");
1025 stmt.registerOutParameter(1,java.sql.Types.INTEGER);
1026 stmt.setLong(2,grp.getID().longValue());
1027 stmt.execute();
1028 boolean res = stmt.getBoolean(1);
1029
1030 return res;
1031 }
1032 catch(SQLException sqle) {
1033 throw new PersistenceException("can't perform document checks, DB error is: ["+
1034 sqle.getMessage()+"]");
1035 }
1036 finally {
1037 DBHelper.cleanup(stmt);
1038 }
1039 }
1040
1041 else if (this.dbType == DBHelper.POSTGRES_DB) {
1042
1043 try {
1044 String sql = "select security_can_delete_group(?)";
1045 pstmt = this.jdbcConn.prepareCall(sql);
1046 pstmt.setLong(1,grp.getID().longValue());
1047 pstmt.execute();
1048 rs = pstmt.getResultSet();
1049
1050 if (false == rs.next()) {
1051 throw new PersistenceException("empty resultset");
1052 }
1053
1054 boolean res = rs.getBoolean(1);
1055
1056 return res;
1057 }
1058 catch(SQLException sqle) {
1059 throw new PersistenceException("can't perform document checks, DB error is: ["+
1060 sqle.getMessage()+"]");
1061 }
1062 finally {
1063 DBHelper.cleanup(rs);
1064 DBHelper.cleanup(pstmt);
1065 }
1066
1067 }
1068
1069 else {
1070 throw new IllegalArgumentException();
1071 }
1072 }
1073
1074
1075 private boolean canDeleteUser(User usr)
1076 throws PersistenceException, SecurityException{
1077
1078 //1. check group localy
1079 if (false == this.usersByID.containsValue(usr)) {
1080 throw new SecurityException("no such user (id=["+usr.getID()+"])");
1081 }
1082
1083 //2. check DB
1084 CallableStatement stmt = null;
1085 PreparedStatement pstmt = null;
1086 ResultSet rs = null;
1087
1088 if (this.dbType == DBHelper.ORACLE_DB) {
1089
1090 try {
1091 stmt = this.jdbcConn.prepareCall(
1092 "{ ? = call "+Gate.DB_OWNER+".security.can_delete_user(?) }");
1093
1094 stmt.registerOutParameter(1,java.sql.Types.INTEGER);
1095 stmt.setLong(2,usr.getID().longValue());
1096 stmt.execute();
1097 boolean res = stmt.getBoolean(1);
1098
1099 return res;
1100 }
1101 catch(SQLException sqle) {
1102 throw new PersistenceException("can't perform document checks, DB error is: ["+
1103 sqle.getMessage()+"]");
1104 }
1105 finally {
1106 DBHelper.cleanup(stmt);
1107 }
1108 }
1109
1110 else if (this.dbType == DBHelper.POSTGRES_DB) {
1111
1112 try {
1113 String sql = "select security_can_delete_user(?) ";
1114 pstmt = this.jdbcConn.prepareCall(sql);
1115 pstmt.setLong(1,usr.getID().longValue());
1116 pstmt.execute();
1117 boolean res = rs.getBoolean(1);
1118
1119 return res;
1120 }
1121 catch(SQLException sqle) {
1122 throw new PersistenceException("can't perform document checks, DB error is: ["+
1123 sqle.getMessage()+"]");
1124 }
1125 finally {
1126 DBHelper.cleanup(rs);
1127 DBHelper.cleanup(pstmt);
1128 }
1129
1130 }
1131
1132 else {
1133 throw new IllegalArgumentException();
1134 }
1135
1136 }
1137
1138 private void init()
1139 throws PersistenceException {
1140
1141 //1. read all groups and users from DB
1142 Statement stmt = null;
1143 ResultSet rs = null;
1144 String sql;
1145 Hashtable groupNames = new Hashtable();
1146 Hashtable groupMembers= new Hashtable();
1147 Hashtable userNames= new Hashtable();
1148 Hashtable userGroups= new Hashtable();
1149
1150 try {
1151 stmt = this.jdbcConn.createStatement();
1152
1153 //1.1 read groups
1154 sql = " SELECT grp_id, " +
1155 " grp_name "+
1156 " FROM "+this.jdbcSchema+"t_group";
1157 rs = stmt.executeQuery(sql);
1158
1159
1160
1161 while (rs.next()) {
1162 //access by index is faster
1163 //first column index is 1
1164 long grp_id = rs.getLong(1);
1165 String grp_name = rs.getString(2);
1166 groupNames.put(new Long(grp_id),grp_name);
1167 groupMembers.put(new Long(grp_id),new Vector());
1168 }
1169 DBHelper.cleanup(rs);
1170
1171
1172 //1.2 read users
1173 sql = " SELECT usr_id, " +
1174 " usr_login "+
1175 " FROM "+this.jdbcSchema+"t_user";
1176 rs = stmt.executeQuery(sql);
1177
1178 while (rs.next()) {
1179 //access by index is faster
1180 //first column index is 1
1181 long usr_id = rs.getLong(1);
1182 String usr_name = rs.getString(2);
1183 userNames.put(new Long(usr_id),usr_name);
1184 userGroups.put(new Long(usr_id),new Vector());
1185 }
1186 DBHelper.cleanup(rs);
1187
1188
1189 //1.3 read user/group relations
1190 sql = " SELECT UGRP_GROUP_ID, " +
1191 " UGRP_USER_ID "+
1192 " FROM "+this.jdbcSchema+"t_user_group " +
1193 " ORDER BY UGRP_GROUP_ID asc";
1194 rs = stmt.executeQuery(sql);
1195
1196 while (rs.next()) {
1197 //access by index is faster
1198 //first column index is 1
1199 Long grp_id = new Long(rs.getLong(1));
1200 Long usr_id = new Long(rs.getLong(2));
1201
1202 //append user to group members list
1203 Vector currMembers = (Vector)groupMembers.get(grp_id);
1204 currMembers.add(usr_id);
1205
1206 Vector currGroups = (Vector)userGroups.get(usr_id);
1207 currGroups.add(grp_id);
1208 }
1209 DBHelper.cleanup(rs);
1210 }
1211 catch(SQLException sqle) {
1212 throw new PersistenceException("DB error is: ["+
1213 sqle.getMessage()+"]");
1214 }
1215 finally {
1216 DBHelper.cleanup(rs);
1217 DBHelper.cleanup(stmt);
1218 }
1219
1220 //2. create USerImpl's and GroupImpl's and put them in collections
1221
1222 //2.1 create Groups
1223 Vector toBeInitializedGroups = new Vector();
1224
1225 Enumeration enGroups = groupNames.keys();
1226 while (enGroups.hasMoreElements()) {
1227 Long grpId = (Long)enGroups.nextElement();
1228 // Vector grpMembers = (Vector)groupMembers.get(grpId);
1229 String grpName = (String)groupNames.get(grpId);
1230
1231 //note that the Vector with group members is empty
1232 //will beinitalized later (ugly hack for bad desgin)
1233 GroupImpl grp = new GroupImpl(grpId,grpName,new Vector(),this,this.jdbcConn);
1234 //register as listener for thsi group
1235 //we care only about name changes
1236 grp.registerObjectModificationListener(this,ObjectModificationEvent.OBJECT_MODIFIED);
1237
1238 //add to collection
1239 this.groupsByID.put(grp.getID(),grp);
1240 this.groupsByName.put(grp.getName(),grp);
1241
1242 //add to vector of the objects to be initialized
1243 toBeInitializedGroups.add(grp);
1244 }
1245
1246 //2.2 create Users
1247 Vector toBeInitializedUsers = new Vector();
1248
1249 Enumeration enUsers = userNames.keys();
1250 while (enUsers.hasMoreElements()) {
1251 Long usrId = (Long)enUsers.nextElement();
1252 // Vector usrGroups = (Vector)userGroups.get(usrId);
1253 String usrName = (String)userNames.get(usrId);
1254
1255 //note that the Vector with user's group is empty
1256 //will be initalized later (ugly hack for bad desgin)
1257 UserImpl usr = new UserImpl(usrId,usrName,new Vector(),this,this.jdbcConn);
1258 //register as listener for thsi user
1259 //we care only about user changing name
1260 usr.registerObjectModificationListener(this,ObjectModificationEvent.OBJECT_MODIFIED);
1261
1262 //add to collection
1263 this.usersByID.put(usr.getID(),usr);
1264 this.usersByName.put(usr.getName(),usr);
1265
1266 //add to vector of the objects to be initialized
1267 toBeInitializedUsers.add(usr);
1268 }
1269
1270 //3. the hack itself:
1271 //all the groups and users are not fully initialized yet
1272 //(the groups/users Vectors are empty)
1273 //initialize them now
1274
1275 //3.1 initialize groups
1276 for (int i=0; i< toBeInitializedGroups.size(); i++) {
1277 GroupImpl grp = (GroupImpl)toBeInitializedGroups.elementAt(i);
1278 grp.setUsers((Vector)groupMembers.get(grp.getID()));
1279 }
1280
1281 //3.2 initialize users
1282 for (int i=0; i< toBeInitializedUsers.size(); i++) {
1283 UserImpl usr = (UserImpl)toBeInitializedUsers.elementAt(i);
1284 usr.setGroups((Vector)userGroups.get(usr.getID()));
1285 }
1286
1287 }
1288
1289
1290 private void fireObjectCreatedEvent(ObjectModificationEvent e) {
1291
1292 //sanity check
1293 if (e.getType() != ObjectModificationEvent.OBJECT_CREATED) {
1294 throw new IllegalArgumentException();
1295 }
1296
1297 for (int i=0; i< this.omCreationListeners.size(); i++) {
1298 ((ObjectModificationListener)this.omCreationListeners.elementAt(i)).objectCreated(e);
1299 }
1300 }
1301
1302
1303 private void fireObjectDeletedEvent(ObjectModificationEvent e) {
1304
1305 //sanity check
1306 if (e.getType() != ObjectModificationEvent.OBJECT_DELETED) {
1307 throw new IllegalArgumentException();
1308 }
1309
1310 for (int i=0; i< this.omDeletionListeners.size(); i++) {
1311 ((ObjectModificationListener)this.omDeletionListeners.elementAt(i)).objectDeleted(e);
1312 }
1313 }
1314
1315
1316 private void fireObjectModifiedEvent(ObjectModificationEvent e) {
1317
1318 //sanity check
1319 if (e.getType() != ObjectModificationEvent.OBJECT_MODIFIED) {
1320 throw new IllegalArgumentException();
1321 }
1322
1323 for (int i=0; i< this.omModificationListeners.size(); i++) {
1324 ((ObjectModificationListener)omModificationListeners.elementAt(i)).objectModified(e);
1325 }
1326 }
1327
1328
1329
1330
1331 public void registerObjectModificationListener(ObjectModificationListener l,
1332 int eventType) {
1333
1334 if (eventType != ObjectModificationEvent.OBJECT_CREATED &&
1335 eventType != ObjectModificationEvent.OBJECT_DELETED &&
1336 eventType != ObjectModificationEvent.OBJECT_MODIFIED) {
1337
1338 throw new IllegalArgumentException();
1339 }
1340
1341 switch(eventType) {
1342 case ObjectModificationEvent.OBJECT_CREATED :
1343 this.omCreationListeners.add(l);
1344 break;
1345 case ObjectModificationEvent.OBJECT_DELETED :
1346 this.omDeletionListeners.add(l);
1347 break;
1348 case ObjectModificationEvent.OBJECT_MODIFIED :
1349 this.omModificationListeners.add(l);
1350 break;
1351 default:
1352 Assert.fail();
1353 }
1354
1355 }
1356
1357 public void unregisterObjectModificationListener(ObjectModificationListener l,
1358 int eventType) {
1359
1360 if (eventType != ObjectModificationEvent.OBJECT_CREATED &&
1361 eventType != ObjectModificationEvent.OBJECT_DELETED &&
1362 eventType != ObjectModificationEvent.OBJECT_MODIFIED) {
1363
1364 throw new IllegalArgumentException();
1365 }
1366
1367 switch(eventType) {
1368 case ObjectModificationEvent.OBJECT_CREATED :
1369 this.omCreationListeners.remove(l);
1370 break;
1371 case ObjectModificationEvent.OBJECT_DELETED :
1372 this.omDeletionListeners.remove(l);
1373 break;
1374 case ObjectModificationEvent.OBJECT_MODIFIED :
1375 this.omModificationListeners.remove(l);
1376 break;
1377 default:
1378 Assert.fail();
1379 }
1380
1381 }
1382
1383
1384
1385
1386 /* ObjectModificationListener methods */
1387
1388 public void objectCreated(ObjectModificationEvent e) {
1389 //I've never registered for these events
1390 Assert.fail();
1391 }
1392
1393 public void objectModified(ObjectModificationEvent e) {
1394
1395 Object source = e.getSource();
1396 int type = e.getType();
1397 int subtype = e.getSubType();
1398
1399 //sanity checks
1400 if (type != ObjectModificationEvent.OBJECT_MODIFIED) {
1401 throw new IllegalArgumentException();
1402 }
1403
1404 //I'm interested only in Groups and Users
1405 if (false == source instanceof Group &&
1406 false == source instanceof User) {
1407
1408 throw new IllegalArgumentException();
1409 }
1410
1411
1412 if (source instanceof Group) {
1413
1414 Assert.assertTrue(subtype == Group.OBJECT_CHANGE_ADDUSER ||
1415 subtype == Group.OBJECT_CHANGE_NAME ||
1416 subtype == Group.OBJECT_CHANGE_REMOVEUSER);
1417
1418 //the name of the group could be different now (IDs are fixed)
1419 if (subtype == Group.OBJECT_CHANGE_NAME) {
1420 //rehash
1421 //any better idea how to do it?
1422 Set mappings = this.groupsByName.entrySet();
1423 Iterator it = mappings.iterator();
1424
1425 boolean found = false;
1426 while (it.hasNext()) {
1427 Map.Entry mapEntry = (Map.Entry)it.next();
1428 String key = (String)mapEntry.getKey();
1429 Group grp = (Group)mapEntry.getValue();
1430
1431 if (false == key.equals(grp.getName())) {
1432 //gotcha
1433 this.groupsByName.remove(key);
1434 this.groupsByName.put(grp.getName(),grp);
1435 found = true;
1436 break;
1437 }
1438 }
1439
1440 Assert.assertTrue(found);
1441 }
1442 }
1443 else {
1444
1445 Assert.assertTrue(source instanceof User);
1446
1447 //the name of the user could be different now (IDs are fixed)
1448
1449 Assert.assertTrue(subtype == User.OBJECT_CHANGE_NAME);
1450
1451 //the name of the group could be different now (IDs are fixed)
1452 if (subtype == User.OBJECT_CHANGE_NAME) {
1453 //rehash
1454 //any better idea how to do it?
1455 Set mappings = this.usersByName.entrySet();
1456 Iterator it = mappings.iterator();
1457
1458 boolean found = false;
1459 while (it.hasNext()) {
1460 Map.Entry mapEntry = (Map.Entry)it.next();
1461 String key = (String)mapEntry.getKey();
1462 User usr = (User)mapEntry.getValue();
1463
1464 if (false == key.equals(usr.getName())) {
1465 //gotcha
1466 this.usersByName.remove(key);
1467 this.usersByName.put(usr.getName(),usr);
1468 found = true;
1469 break;
1470 }
1471 }
1472
1473 Assert.assertTrue(found);
1474 }
1475 }
1476
1477
1478 }
1479
1480 public void objectDeleted(ObjectModificationEvent e) {
1481 //I've never registered for these events
1482 Assert.fail();
1483 }
1484
1485 public void processGateEvent(GateEvent e){
1486 throw new MethodNotImplementedException();
1487 }
1488
1489 /** -- */
1490 public boolean isValidSecurityInfo(SecurityInfo si) {
1491
1492 switch(si.getAccessMode()) {
1493
1494 case SecurityInfo.ACCESS_WR_GW:
1495 case SecurityInfo.ACCESS_GR_GW:
1496 return (null != si.getGroup());
1497
1498 case SecurityInfo.ACCESS_GR_OW:
1499 return (null != si.getGroup() &&
1500 null != si.getUser());
1501
1502 case SecurityInfo.ACCESS_OR_OW:
1503 return (null != si.getUser());
1504
1505 default:
1506 throw new IllegalArgumentException();
1507 }
1508 }
1509
1510 public void finalize() {
1511 //close connection
1512 try {
1513 this.jdbcConn.close();
1514 }
1515 catch(SQLException sqle) {}
1516
1517 }
1518
1519 }
|