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

📄 jndibroker.java

📁 JAVA开源LDAP浏览器jxplorer的源码!
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
package com.ca.directory.jxplorer.broker;

import javax.naming.*;
import javax.naming.directory.*;


import java.util.*;
import java.util.logging.Logger;
import java.util.logging.Level;
import java.io.*;

import com.ca.directory.jxplorer.*;
import com.ca.commons.naming.*;
import com.ca.commons.cbutil.*;
import com.ca.commons.jndi.*;




/**
*	This utility class handles all the JNDIBroker LDAP calls, returning objects
*  	to calling classes and managing the connection.<p>
*
*  	Before examining this class make sure to examing the base Broker class thoroughly.
*  	The base Broker class takes user requests, and creates DataQuery objects.  A
*  	separate thread takes these DataQuery objects and uses the methods of derived
*  	classes (such as this one) to do the actual grunt work.
*/

public class JNDIBroker  extends Broker
{
//  	private static final String DEFAULT_CTX = "com.sun.jndi.ldap.LdapCtxFactory";
    private static final int    SEARCHLIMIT = 0;
    private static final int    SEARCHTIMEOUT = 0;

    /**
     *   Used as a parameter to unthreadedSearch, this specifies to only search
     *   the base object.
     */

    public static final int SEARCH_BASE_OBJECT = 0;

    /**
     *   Used as a parameter to unthreadedSearch, this specifies to only search
     *   the next level from the current DN.
     */

    public static final int SEARCH_ONE_LEVEL = 1;

    /**
     *   Used as a parameter to unthreadedSearch, this specifies to search
     *   the entire subtree from the current DN.
     */

    public static final int SEARCH_SUB_TREE = 2;

  	private DirContext ctx;
//    private DirContext schemactx;
//    private Attributes schemaOps;
    private boolean tracing = false;
    private boolean connectionError = true;


    private Hashtable attributeNames;

    private boolean quietMode = false;     			// suppress gui ops (esp. error msgs.)
    private boolean errorWhileQuietFlag = false; 	// used when broker is in 'quiet gui mode'.

  	int limit   = SEARCHLIMIT;             			// default number of results returned.
    int timeout = SEARCHTIMEOUT;           			// default timeout.

    static int threadID = 1;               			// debug identifier for thread tracking
    static final boolean DEBUGTHREADS = false; 		// debug flag for threadiness

    private CBGraphicsOps dirOps = null;   			// the low level directory operations class.
    private SchemaOps schemaOps;                    // the low level schemaOps class

    private HashSet specialObjectClasses;  			// OS390 hack

    private final static Logger log = Logger.getLogger(JNDIBroker.class.getName());

   /**
	*  	Helper class for Broker, this encapsulates an ldap-like connection
	*  	request that is placed on the Broker queue for eventual resolution.
	*  	The Connection Request object is intended to be used once, and then
	*  	discarded.
	*/

    public class DataConnectionQuery extends DataQuery
    {
		public final ConnectionData conData;


	   /**
		*   Defines a request to open a connection to an LDAP (only) server.
		*	@param cData a data object containing connection information.
		*/

		public DataConnectionQuery(ConnectionData cData)
		{
            super(DataQuery.EXTENDED);

			conData = cData;

            setExtendedData("version", String.valueOf(conData.version));
            setExtendedData("url", conData.getURL());
		}



	   /**
		*    Utility name translation method
		*/

        public String getTypeString()
        {
            return super.getTypeString() + " Connection Request";
        }
    }



   /**
    *	Constructor does nothing except create an env object ( 'connect()'
    *   is used to open a connection)
    */

    public JNDIBroker()
    {
        initSpecialObjectClasses();
    }



   /**
	*  	Clones a JNDIBroker, using the same underlying directory connection,
	*  	but clearing the data listener list, and having its own debug flags.
	*  	Any StopMonitors however will need to be re-registered with the new
	*  	Broker.
	*	@param cloneMe
	*/

    public JNDIBroker(JNDIBroker cloneMe)
    {
        registerDirectoryConnection(cloneMe);
    }



   /**
	* 	Resets a JNDIBroker, using the same underlying directory connection
	*  	as the passed broker, but clearing the data listener list, and resetting debug flags.
	*  	Any StopMonitors however will need to be re-registered.
	*	@param cloneMe
	*/

    public void registerDirectoryConnection(JNDIBroker cloneMe)
    {
        ctx = cloneMe.ctx;
//        schemaOps = cloneMe.schemaOps;
        tracing = cloneMe.tracing;
        connectionError = cloneMe.connectionError;
        attributeNames = cloneMe.attributeNames;

        limit   = cloneMe.limit;
        timeout = cloneMe.timeout;

        dirOps = cloneMe.dirOps;
        schemaOps = cloneMe.schemaOps;

        specialObjectClasses = cloneMe.specialObjectClasses;  // OS390 hack
    }



   /**
	*  	Mitch/OS390 hack
	*/

    protected void initSpecialObjectClasses()
    {
        String fileName = System.getProperty("user.dir") + File.separator + "specialocs.txt";
        if (new File(fileName).exists())
        {
            try
            {
                String text = CBUtility.readTextFile(new File(fileName));
                StringTokenizer st = new StringTokenizer(text);
                specialObjectClasses = new HashSet(10);
                while (st.hasMoreTokens())
                {
                    String oc = st.nextToken();
                    specialObjectClasses.add(oc);
                }
            }
            catch (Exception e)
            {
                log.info("unable to obtain special object classes list:\n  " + e.toString());
                specialObjectClasses = null;
            }
        }
    }



   /**
	*  	Suppresses user notification of errors via GUI dialogs,
	*  	and logs them instead.  Necessary for large batch ops. like
	*  	importing an ldif file.
	*	@param status
	*/

    public void setGUIQuiet(boolean status)
    {
        quietMode = status;
        dirOps.setQuietMode(status);

        if (quietMode == false)
            setQuietError(false);  // clear quiet error flag.
    }



   /**
	*  	Sets the quiet error flag status.
	*	@param status
	*/

    public void setQuietError(boolean status)
    {
        errorWhileQuietFlag = status;
    }



   /**
	*  	This returns whether one or more errors occured while the
	*  	program was in 'quiet gui' (i.e. no error dialogs) mode.
	*  	It does not return the actual error, since frequently there
	*  	were many: the user should consult the log file.
	*	@return
	*/

    public boolean getQuietError()
    {
        return (errorWhileQuietFlag || dirOps.errorWhileQuietFlag);
    }


   /**
	*  	Sets ber tracing status.  Set to true this generates a huge
	*  	amount of comms. tracing info, <i>when the next connection is opened</i>.
	*  	It doesn't seem possible to set it for an already open connection, so
	*  	we no longer even try.
	*	@param traceStatus
	*/

    public void setTracing(boolean traceStatus)
    {
        tracing = traceStatus;
    }

    /**
     *  	Returns ber tracing status.  When true this generates a huge
     *  	amount of comms. tracing info, <i>when the next connection is opened</i>.
     *  	It doesn't seem possible to set it for an already open connection, so
     *  	we no longer even try.
     *	    @return the traceStatus
     */

    public boolean getTracing() { return tracing; }

   /**
	*   <p>Queues a request to open a connection to an LDAP (only) server.</p>
	*
	*   <p>Note that some rarely modified connection status variables are set externally - e.g.
	*   BER tracing status (derived from the log level, set by setTracing() ),
	*   and the security keystore type and external security provider (if any)
	*   which are set in the config file).</p>
	*
	*   @param baseDN          		the base DN from which to browse.
	*   @param version         		the LDAP Version (2 or 3) being used.
	*   @param host            		the LDAP server url.
	*   @param port            		the LDAP server port (default 389) being used.
	*   @param userDN		   		the Manager User's DN - (is null if user is not manager)
	*   @param pwd             		the Manager User's password - (is null if user is not manager)
	*   @param referralType    		the jndi ldap referral type: [follow:ignore:throw]
	*   @param aliasType			how aliases are handled: 'always'|'never'|'finding'|'searching'
	*   @param useSSL          		whether to use SSL for encryption and/or authentication (dependant on other parameters)
	*   @param cacerts		      	path to a store of trusted server certificates or CA certificates - required for Server-auth ssl
	*   @param clientcerts		  	path to client certificates - if available, will use for client authentication
	*	@param caKeystorePwd		the password to the client's keystore (may be null for non-client authenticated ssl).
	*   @param clientKeystorePwd	the password to the client certificates - required to use client certs for authentication
	*   @deprecated            		use connect(ConnectionData) instead.
	*   @return                		returns the thread that is used to make the connection
	*/

    // nb capitalisation of 'cacerts' and 'clientcerts' wierd to match actual default file names.

  	public DataQuery connect(String baseDN, int version, String host,
          int port, String userDN, char[] pwd,
          String referralType, String aliasType, boolean useSSL,
          String cacerts, String clientcerts,
          char[] caKeystorePwd, char[] clientKeystorePwd)
  	{
		ConnectionData cData = new ConnectionData();
		cData.setURL(host,port);

		cData.baseDN 				= baseDN;
		cData.version				= version;
		cData.setURL(host, port);
		cData.userDN				= userDN;
		cData.pwd					= pwd;
		cData.referralType 			= referralType;
		cData.aliasType				= aliasType;
		cData.useSSL				= useSSL;
		cData.cacerts				= cacerts;
		cData.clientcerts 			= clientcerts;
		cData.caKeystorePwd			= caKeystorePwd;
		cData.clientKeystorePwd		= clientKeystorePwd;
        cData.tracing               = getTracing();
        return connect(cData);
    }



   /**
	* 	<p>Queues a request to open a connection to an LDAP (only) server.</p>
	*
	*   <p>Note that some rarely modified connection status variables are set externally - e.g.
	*   BER tracing status (derived from the log level, set by setTracing() ),
	*   and the security keystore type and external security provider (if any)
	*   which are set in the config file).</p>
	* 	@param cData data object containing all the connection information.
	*   @return returns the thread that is used to make the connection
	*/

  	public DataQuery connect(ConnectionData cData)
  	{
        cData.caKeystoreType     = JXplorer.getProperty("keystoreType.cacerts", "JKS");
        cData.clientKeystoreType = JXplorer.getProperty("keystoreType.clientcerts", "JKS");

        DataQuery openCon = new DataConnectionQuery(cData);

        return push(openCon);
    }



   /**
	*  	Extends the base class processRequest method to handle DataConnectionRequest objects.
	*	@param request the connection data query.
	*/

    protected void processRequest(DataQuery request)
    {
        try
        {
            if (request instanceof DataConnectionQuery)
                openConnection((DataConnectionQuery) request);
            else
                super.processRequest(request);
        }
        catch (Exception e)
        {
            request.setException(e);
            e.printStackTrace();
        }
    }



   /**
	*   Does the actual grunt work of opening a new connection.
	*	@param request a DataQuery object that contains the connection details.
	*	@return the data query object.
	*/

    protected DataQuery openConnection(DataConnectionQuery request)
    {
        disconnect(); // clear out any existing cobwebs...

		ConnectionData cData = request.conData;

        String url = cData.url;

        connectionError = false;

        ctx = null;    // null the current directory context (can't be used again).

        //  Try to get a directory context using above info.

        try
        {
            dirOps = new CBGraphicsOps(cData);        	// this wraps up ctx for basic operations
            ctx = dirOps.getContext();

            if (ctx == null)
                throw new NamingException("unable to open connection: unknown condition, no error returned.");

            // make a bogus, fast, directory request to trigger some activity on the context.  Without this the
            // context may *appear* to be open since jndi sometimes won't actually try to use it until a request is made
            // (e.g. with DSML, SSL connections etc.)

            String base = (request.conData.baseDN==null)?"":request.conData.baseDN;

            //XXX bogus request failing - why??? (ans SASL error in jdk 1.4.0 - 1.4.1)
            //ctx.search(base, "objectClass=*", new SearchControls(SearchControls.OBJECT_SCOPE, 0, 0, new String[]{}, false, false));
            if (dirOps.exists(base) == false)
                cData.baseDN = getActualDN(cData.baseDN);	//TE: (for bug 2363) - try to solve case sensitive DN problem.

            // At this stage we should have a valid ldap context
        }
        // can throw NamingException, GeneralSecurityException, IOException
        catch (Exception ne)        // An error has occurred.  Exit connection routine
        {                                 // taking no further action.
            log.warning("initial receipt of exception by jndi broker " + ne.getMessage());
            ne.printStackTrace();
            request.setException(ne);
            request.setStatus(false);
            request.finish();
            return request;
        }

        try
        {
            schemaOps = new SchemaOps(ctx); 
        }        		// this wraps up ctx for basic operations
        catch (NamingException e)
        {
            log.log(Level.WARNING, "unable to init schemaOps Ops ", e);
            schemaOps = null;
        }

        if (schemaOps != null && (cData.protocol == ConnectionData.DSML || cData.version > 2))    					// if ldap 3 or better try to open a schemaOps context
        {
            try
            {
                String binaries = schemaOps.getNewBinaryAttributes();
                if (binaries.trim() != "")
                    ctx.addToEnvironment("java.naming.ldap.attributes.binary", binaries);
                initAttributeNamesHash();
            }

⌨️ 快捷键说明

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