⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 poolelement.java

📁 使用工具jublider开发的一个聊天室实现基本功能,
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/**
 * Copyright (C) 2003  Manfred Andres
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
package freecs.auth.sqlConnectionPool;

import freecs.Server;
import freecs.core.CanceledRequestException;
import freecs.core.User;
import freecs.interfaces.IUserStates;
import freecs.util.HashUtils;

import java.sql.*;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;

public class PoolElement {
    public static final short INVALID = -1;
    public static final short IDLE    = 0;
    public static final short ACTIVE  = 1;
    
    volatile private PreparedStatement select = null,
                                       update = null,
                                       updateLastlogin = null,
                                       insert = null;
    volatile private String            selStrg = null,
                                       insStrg = null,
                                       updStrg = null,
                                       updLastloginStrg = null;
    private DbProperties dbp;
    private volatile boolean isValid=true;

    ConnectionPool pool;
    Connection con = null;
    int id;
    volatile int sCnt=0; 
    long validUntil;
    volatile boolean isActive = false, hasBeenUsed=false, cleanedUp=false;
    ResultSet rs;

    PoolElement (ConnectionPool pool, Connection con, DbProperties dbp, int id) throws Exception {
        if (con == null) 
            throw new Exception ("no connection supplied");
        this.pool = pool;
        this.dbp=dbp;
        this.id = id;
        this.con = con;
        con.setAutoCommit (false);
        validUntil = System.currentTimeMillis() + dbp.conTTL;
        Server.log ("SqlAuthenticator", "Created new Connetion " + this.toString(), Server.MSG_AUTH, Server.LVL_MAJOR);
        if (Server.TRACE_CREATE_AND_FINALIZE)
            Server.log (this, "++++++++++++++++++++++++++++++++++++++++CREATE", Server.MSG_STATE, Server.LVL_VERY_VERBOSE);
    }

	private boolean isValid() {
        if (!isValid)
            return false;
        if (con == null
            || cleanedUp)
            return false;
        if (!hasBeenUsed)
            return true;
        if (sCnt > dbp.maxStmtPerCon) {
            Server.log(this, "invalid because max-statements/connection has been reached " + dbp.maxStmtPerCon, Server.MSG_AUTH, Server.LVL_VERBOSE);
            isValid=false;
            return false;
        }
        if (validUntil <= System.currentTimeMillis()) {
            Server.log(this, "invalid because connection ttl has been reached " + dbp.conTTL, Server.MSG_AUTH, Server.LVL_VERBOSE);
            isValid=false;
            return false;
        }
        return true;
    }
    
	/**
	 * causes this PoolElement to close all open cursors and the connection to it's jdbc-source
	 */
    public synchronized void cleanup () {
        if (cleanedUp)
            return;
        try {
            if (select != null) {
                select.close();
                select = null;
            }
        } catch (SQLException se) {
            Server.debug(this, "cleanup: select.close()", se, Server.MSG_ERROR, Server.LVL_MAJOR);
        }
        try {
            if (insert != null) {
                insert.close();
                insert = null;
            }
        } catch (SQLException se) {
            Server.debug(this, "cleanup: insert.close()", se, Server.MSG_ERROR, Server.LVL_MAJOR);
        }
        try {
            if (update != null) {
                update.close();
                update = null;
            }
        } catch (SQLException se) {
            Server.debug(this, "cleanup: update.close()", se, Server.MSG_ERROR, Server.LVL_MAJOR);
        }
        try {
            if (con!=null) {
                con.close();
                con = null;
            }
        } catch (SQLException se) {
            Server.debug(this, "cleanup: connection.close()", se, Server.MSG_ERROR, Server.LVL_MAJOR);
        }
        this.pool = null;
        this.isActive = false;
        this.cleanedUp = true;
        Server.log ("SqlAuthenticator", "Closed Connetion " + this.toString(), Server.MSG_AUTH, Server.LVL_MAJOR);        
    }

    /**
     * Checks the given Statement for SQLWarnings and logs them.
     * @param s The statement to check for Warnings
     */
	public void checkWarnings(Statement s, String prefix) {
        try {
    		SQLWarning sqlW = s.getWarnings();
    		while (sqlW != null) {
    			  StringBuffer sb = new StringBuffer(this.toString());
                  sb.append (" getResultSet: Encountered SQLWarning: ");
                  sb.append (prefix);
                  sb.append (": ");
    			  sb.append (sqlW.getErrorCode());
    			  sb.append (": ");
    			  sb.append (sqlW.getCause());
    			  Server.log (Thread.currentThread(), sb.toString (), Server.MSG_ERROR, Server.LVL_MAJOR);
    			  sqlW = sqlW.getNextWarning();
    		}
        } catch (SQLException se) {
            this.isValid=false;
            Server.debug(this, "checkWarnings caused exception", se, Server.MSG_ERROR, Server.LVL_MAJOR);
        }
	}

    public String toString() {
        StringBuffer sb = new StringBuffer("[PoolElement: ");
        sb.append (id);
        sb.append ("/");
        sb.append (sCnt);
        sb.append ("/");
        sb.append (dbp.url).append ("(").append (dbp.table).append(")");
        sb.append ("]");
        return sb.toString();
    }

    /**
     * Grabs control over this PoolElement and returns true on success
     * @return true if the control over this PoolElement was grabbed successfully
     */
    public synchronized short grab() {
        if (this.isActive)
            return ACTIVE;
        if (!isValid())
            return INVALID;
        this.isActive=true;
        this.hasBeenUsed=true;
        return IDLE;
    }

    /**
     * Clears all parameters given to the PreparedStatements and all their warnings. 
     * Afterwards this PoolElement is marked as inactive (isActive = false)
     */
    public void release() {
        try {
            if (select!=null) {
                select.clearParameters();
                select.clearWarnings();
            }
            if (update!=null) {
                update.clearParameters();
                update.clearWarnings();
            }
            if (insert!=null) {
                insert.clearParameters();
                insert.clearWarnings();
            }
        } catch (Exception se) {
            Server.debug (this, "catched exception while releasing PoolElement", se, Server.MSG_AUTH, Server.LVL_MAJOR);
        }
        this.isActive=false;
    }

    /**
     * Checks if a PreparedStatement for selection is already constructed or a 
     * new PreparedStatement will be constructed and this PreparedStatement will
     * be returned
     * @return the PreparedStatement for selection
     * @throws Exception if an Error occured
     */
    private PreparedStatement getSelect() throws Exception {
        try {
            if (select!=null)
                return select;
            if (con==null)
                throw new Exception ("No connection to retrieve a PreparedStatement from");
            StringBuffer sb = new StringBuffer ("SELECT ");
            sb.append (dbp.columns[0]);
            for (int i = 1; i<dbp.columns.length; i++) {
                sb.append (", ");
                sb.append (dbp.columns[i]);
            }
            sb.append (", ");
            sb.append (dbp.fc_password);
            sb.append (" FROM ");
            sb.append (dbp.table);
            sb.append (" WHERE ");
            sb.append (dbp.fc_username);
            sb.append (" = ?");
            selStrg = sb.toString();
            select = con.prepareStatement(selStrg, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
            if (dbp.queryTimeout > 0)
                select.setQueryTimeout(dbp.queryTimeout);
            return select;
        } catch (Exception e) {
            isValid=false;
            release();
            throw e;
        }
    }

    private PreparedStatement getUpdate() throws Exception {
        try {
            if (update != null)
                return update;
            if (con==null)
                throw new Exception ("No connection to retrieve a PreparedStatement from");
            StringBuffer sb = new StringBuffer("UPDATE ");
            sb.append (dbp.table);
            sb.append (" SET ");
            sb.append (dbp.updCols[0]);
            sb.append (" = ?");
            for (int i = 1; i<dbp.updCols.length; i++) {
                sb.append (", ");
                sb.append (dbp.updCols[i]);
                sb.append (" = ?");
            }
            sb.append (" WHERE ");
            if (dbp.idField != null) {
                sb.append (dbp.idField);
                sb.append (" = ?");
            } else {
                sb.append (dbp.fc_username);
                sb.append (" = ?");
            }
            updStrg = sb.toString();
            update = con.prepareStatement(updStrg);
            if (dbp.queryTimeout > 0)
                update.setQueryTimeout(dbp.queryTimeout);
            return update;
        } catch (Exception e) {
            isValid=false;
            release();
            throw e;
        }
    }

   
    /**
     * Checks if there is already a PreparedStatement for retrieving the user-data and
     * constructs it, if it doesn't exist. Afterwards the login will be checked and
     * the user-object will be constructed if the credentials are correct. Null will
     * be returned, if the credentials did not return a user-record.
     * @return User the user which is allowed to log in or null if no match was found
     * @throws Exception if technical error occures (connection problems, ...)
     */
    public User loginUser (String username, String password, String cookie) throws Exception {
        try {
            checkThread();
            PreparedStatement ps = getSelect();
            ps.setString(1, username.toLowerCase().trim());
            ResultSet rs = ps.executeQuery(); 
            sCnt++;
            Server.log(Thread.currentThread(), this.toString() + "LOGIN user uname=" + username.toLowerCase() + "/pwd=" + password + "/cookie=" + cookie + "\r\n" + selStrg, Server.MSG_AUTH, Server.LVL_VERY_VERBOSE);
            dbp.cacheMetaData(rs);
            if (!rs.next()) {
                Server.log(Thread.currentThread(), this.toString()+ "LOGIN no user mathing username and password " + username + "/" + password, Server.MSG_AUTH, Server.LVL_MINOR);
                rs.close();
                // return unregistered user (if they are allowed will be checked in auth-manager)
                return new User(username, cookie); // return an unregistered user
            } else if (!rs.isLast()) {
                Server.log(Thread.currentThread(), this.toString() + "LOGIN multible records returned for user " + username, Server.MSG_AUTH, Server.LVL_MAJOR);
                rs.close();
                // return null to make clear, that there is a problem within the db-table
                return null;
            }
            checkThread();
            String dbpwd = rs.getString(dbp.columns.length+1);
            if (dbpwd==null || !dbpwd.equals(password))
                return null;
            
            User u = new User (username, cookie);
            u.isUnregistered = false;
            
            readColumns(u, rs);
            
            checkWarnings(ps, "loginUser (getData)");
            
            checkThread();
            // if a lastlogin-property exists, we have to update the data in the db
            if (!dbp.readOnly) {
            	doLoginUpdates(u, rs);
            }
            checkWarnings(ps, "loginUser (update Data)");
            rs.close();
            Server.log (Thread.currentThread(), this.toString() + "LOGIN returning " + u, Server.MSG_AUTH, Server.LVL_MAJOR);
            u.isUnregistered = false;
            return u;
        } catch (Exception e) {
            Server.debug (this, selStrg, e, Server.MSG_AUTH, Server.LVL_MAJOR);
            isValid=false;
            release();
            throw e;
        }
    }

    public User loginUser (User u, String password) throws Exception {
        try {
            checkThread();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -