/* $Id: AuthorityConnector.java 988245 2010-08-23 18:39:35Z kwright $ */

/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.manifoldcf.crawler.authorities.DCTM;

import org.apache.log4j.*;
import org.apache.manifoldcf.core.interfaces.*;
import org.apache.manifoldcf.agents.interfaces.*;
import org.apache.manifoldcf.authorities.interfaces.*;
import org.apache.manifoldcf.authorities.system.Logging;
import java.util.*;
import java.io.*;
import org.apache.manifoldcf.crawler.common.DCTM.*;
import java.rmi.*;


/** Autheticator.
*/
public class AuthorityConnector extends org.apache.manifoldcf.authorities.authorities.BaseAuthorityConnector
{

  public static final String CONFIG_PARAM_DOCBASE = "docbasename";
  public static final String CONFIG_PARAM_USERNAME = "docbaseusername";
  public static final String CONFIG_PARAM_PASSWORD = "docbasepassword";
  public static final String CONFIG_PARAM_DOMAIN = "domain";
  public static final String CONFIG_PARAM_CASEINSENSITIVE = "usernamecaseinsensitive";
  public static final String CONFIG_PARAM_USESYSTEMACLS = "usesystemacls";
  public static final String CONFIG_PARAM_CACHELIFETIME = "cachelifetimemins";
  public static final String CONFIG_PARAM_CACHELRUSIZE = "cachelrusize";
  
  protected String docbaseName = null;
  protected String userName = null;
  protected String password = null;
  protected String domain = null;
  protected boolean caseInsensitive = false;
  protected boolean useSystemAcls = true;

  // Documentum has no "deny" tokens, and its document acls cannot be empty, so no local authority deny token is required.
  // However, it is felt that we need to be suspenders-and-belt, so here is the deny token.
  // The documentum tokens are of the form xxx:yyy, so they cannot collide with the standard deny token.
  protected static final String denyToken = "DEAD_AUTHORITY";

  protected static final AuthorizationResponse unreachableResponse = new AuthorizationResponse(new String[]{denyToken},AuthorizationResponse.RESPONSE_UNREACHABLE);
  protected static final AuthorizationResponse userNotFoundResponse = new AuthorizationResponse(new String[]{denyToken},AuthorizationResponse.RESPONSE_USERNOTFOUND);
  protected static final AuthorizationResponse userUnauthorizedResponse = new AuthorizationResponse(new String[]{denyToken},AuthorizationResponse.RESPONSE_USERUNAUTHORIZED);

    /** Cache manager. */
  protected ICacheManager cacheManager = null;

  // This is the DFC session; it may be null, or it may be set.
  protected IDocumentum session = null;
  protected long lastSessionFetch = -1L;

  protected static final long timeToRelease = 300000L;

  private String cacheLifetime = null;
  private String cacheLRUsize = null;
  private long responseLifetime = 60000L;
  private int LRUsize = 1000;

  public AuthorityConnector()
  {
    super();
  }

  /** Set thread context.
  */
  @Override
  public void setThreadContext(IThreadContext tc)
    throws ManifoldCFException
  {
    super.setThreadContext(tc);
    cacheManager = CacheManagerFactory.make(tc);
  }
  
  /** Clear thread context.
  */
  @Override
  public void clearThreadContext()
  {
    super.clearThreadContext();
    cacheManager = null;
  }

  protected class GetSessionThread extends Thread
  {
    protected Throwable exception = null;

    public GetSessionThread()
    {
      super();
      setDaemon(true);
    }

    public void run()
    {
      try
      {
        // Create a session
        IDocumentumFactory df = (IDocumentumFactory)Naming.lookup("rmi://127.0.0.1:8300/documentum_factory");
        IDocumentum newSession = df.make();
        newSession.createSession(docbaseName,userName,password,domain);
        session = newSession;
      }
      catch (Throwable e)
      {
        this.exception = e;
      }
    }

    public Throwable getException()
    {
      return exception;
    }
  }

  /** Get a DFC session.  This will be done every time it is needed.
  */
  protected void getSession()
    throws ManifoldCFException
  {
    try
    {
      responseLifetime = Long.parseLong(this.cacheLifetime) * 60L * 1000L;
      LRUsize = Integer.parseInt(this.cacheLRUsize);
    }
    catch (NumberFormatException e)
    {
      throw new ManifoldCFException("Cache lifetime or Cache LRU size must be an integer: "+e.getMessage(),e);
    }

    if (session == null)
    {
      // This is the stuff that used to be in connect()
      if (docbaseName == null || docbaseName.length() < 1)
        throw new ManifoldCFException("Parameter "+CONFIG_PARAM_DOCBASE+" required but not set");

      if (Logging.authorityConnectors.isDebugEnabled())
        Logging.authorityConnectors.debug("DCTM: Docbase = '" + docbaseName + "'");

      if (userName == null || userName.length() < 1)
        throw new ManifoldCFException("Parameter "+CONFIG_PARAM_USERNAME+" required but not set");

      if (Logging.authorityConnectors.isDebugEnabled())
        Logging.authorityConnectors.debug("DCTM: Username = '" + userName + "'");

      if (password == null || password.length() < 1)
        throw new ManifoldCFException("Parameter "+CONFIG_PARAM_PASSWORD+" required but not set");

      Logging.authorityConnectors.debug("DCTM: Password exists");

      if (domain == null)
      {
        // Empty domain is allowed
        Logging.authorityConnectors.debug("DCTM: No domain");
      }
      else
        Logging.authorityConnectors.debug("DCTM: Domain = '" + domain + "'");

      if (caseInsensitive)
      {
        Logging.authorityConnectors.debug("DCTM: Case insensitivity enabled");
      }

      if (useSystemAcls)
      {
        Logging.authorityConnectors.debug("DCTM: Use system acls enabled");
      }


      // This actually sets up the connection
      GetSessionThread t = new GetSessionThread();
      try
      {
        t.start();
        t.join();
        Throwable thr = t.getException();
        if (thr != null)
        {
          if (thr instanceof java.net.MalformedURLException)
            throw (java.net.MalformedURLException)thr;
          else if (thr instanceof NotBoundException)
            throw (NotBoundException)thr;
          else if (thr instanceof RemoteException)
            throw (RemoteException)thr;
          else if (thr instanceof DocumentumException)
            throw (DocumentumException)thr;
          else if (thr instanceof RuntimeException)
            throw (RuntimeException)thr;
          else
            throw (Error)thr;
        }
      }
      catch (InterruptedException e)
      {
        t.interrupt();
        throw new ManifoldCFException("Interrupted: "+e.getMessage(),e,ManifoldCFException.INTERRUPTED);
      }
      catch (java.net.MalformedURLException e)
      {
        throw new ManifoldCFException(e.getMessage(),e);
      }
      catch (NotBoundException e)
      {
        // Transient problem: Server not available at the moment.
        throw new ManifoldCFException("Server not up at the moment: "+e.getMessage(),e);
      }
      catch (RemoteException e)
      {
        Throwable e2 = e.getCause();
        if (e2 instanceof InterruptedException || e2 instanceof InterruptedIOException)
          throw new ManifoldCFException(e2.getMessage(),e2,ManifoldCFException.INTERRUPTED);
        session = null;
        lastSessionFetch = -1L;
        // Treat this as a transient problem
        throw new ManifoldCFException("Transient remote exception creating session: "+e.getMessage(),e);
      }
      catch (DocumentumException e)
      {
        // Base our treatment on the kind of error it is.
        if (e.getType() == DocumentumException.TYPE_SERVICEINTERRUPTION)
        {
          throw new ManifoldCFException("Remote service interruption creating session: "+e.getMessage(),e);
        }
        throw new ManifoldCFException(e.getMessage(),e);
      }
    }

    // Update the expire time for this session, except if an error was thrown.
    lastSessionFetch = System.currentTimeMillis();

  }

  /** Perform a DQL query, with appropriate reset on a remote exception */
  protected IDocumentumResult performDQLQuery(String query)
    throws DocumentumException, ManifoldCFException
  {
    while (true)
    {
      boolean noSession = (session==null);
      getSession();
      try
      {
        return session.performDQLQuery(query);
      }
      catch (RemoteException e)
      {
        if (noSession)
          throw new ManifoldCFException("Transient error connecting to documentum service",e);
        session = null;
        lastSessionFetch = -1L;
        continue;
      }
    }
  }

  protected class CheckConnectionThread extends Thread
  {
    protected Throwable exception = null;

    public CheckConnectionThread()
    {
      super();
      setDaemon(true);
    }

    public void run()
    {
      try
      {
        session.checkConnection();
      }
      catch (Throwable e)
      {
        this.exception = e;
      }
    }

    public Throwable getException()
    {
      return exception;
    }

  }

  /** Check connection, with appropriate retries */
  protected void checkConnection()
    throws DocumentumException, ManifoldCFException
  {
    while (true)
    {
      boolean noSession = (session==null);
      getSession();
      CheckConnectionThread t = new CheckConnectionThread();
      try
      {
        t.start();
        t.join();
        Throwable thr = t.getException();
        if (thr != null)
        {
          if (thr instanceof RemoteException)
            throw (RemoteException)thr;
          else if (thr instanceof DocumentumException)
            throw (DocumentumException)thr;
          else if (thr instanceof RuntimeException)
            throw (RuntimeException)thr;
          else
            throw (Error)thr;
        }
        return;
      }
      catch (InterruptedException e)
      {
        t.interrupt();
        throw new ManifoldCFException("Interrupted: "+e.getMessage(),e,ManifoldCFException.INTERRUPTED);
      }
      catch (RemoteException e)
      {
        Throwable e2 = e.getCause();
        if (e2 instanceof InterruptedException || e2 instanceof InterruptedIOException)
          throw new ManifoldCFException(e2.getMessage(),e2,ManifoldCFException.INTERRUPTED);
        if (noSession)
          throw new ManifoldCFException("Transient error connecting to documentum service",e);
        session = null;
        lastSessionFetch = -1L;
        continue;
      }
    }
  }

  /** Perform getObjectByQualification, with appropriate reset */
  protected IDocumentumObject getObjectByQualification(String qualification)
    throws DocumentumException, ManifoldCFException
  {
    while (true)
    {
      boolean noSession = (session==null);
      getSession();
      try
      {
        return session.getObjectByQualification(qualification);
      }
      catch (RemoteException e)
      {
        if (noSession)
          throw new ManifoldCFException("Transient error connecting to documentum service",e);
        session = null;
        lastSessionFetch = -1L;
        continue;
      }
    }

  }

  /** Get server version, with appropriate retries */
  protected String getServerVersion()
    throws DocumentumException, ManifoldCFException
  {
    while (true)
    {
      boolean noSession = (session==null);
      getSession();
      try
      {
        return session.getServerVersion();
      }
      catch (RemoteException e)
      {
        if (noSession)
          throw new ManifoldCFException("Transient error connecting to documentum service",e);
        session = null;
        lastSessionFetch = -1L;
        continue;
      }
    }

  }


  protected class DestroySessionThread extends Thread
  {
    protected Throwable exception = null;

    public DestroySessionThread()
    {
      super();
      setDaemon(true);
    }

    public void run()
    {
      try
      {
        session.destroySession();
      }
      catch (Throwable e)
      {
        this.exception = e;
      }
    }

    public Throwable getException()
    {
      return exception;
    }

  }


  /** Release the session, if it's time.
  */
  protected void releaseCheck()
    throws ManifoldCFException
  {
    if (lastSessionFetch == -1L)
      return;

    long currentTime = System.currentTimeMillis();
    if (currentTime >= lastSessionFetch + timeToRelease)
    {
      DestroySessionThread t = new DestroySessionThread();
      try
      {
        t.start();
        t.join();
        Throwable thr = t.getException();
        if (thr != null)
        {
          if (thr instanceof RemoteException)
            throw (RemoteException)thr;
          else if (thr instanceof DocumentumException)
            throw (DocumentumException)thr;
          else if (thr instanceof RuntimeException)
            throw (RuntimeException)thr;
          else
            throw (Error)thr;
        }
        session = null;
        lastSessionFetch = -1L;
      }
      catch (InterruptedException e)
      {
        t.interrupt();
        throw new ManifoldCFException("Interrupted: "+e.getMessage(),e,ManifoldCFException.INTERRUPTED);
      }
      catch (RemoteException e)
      {
        Throwable e2 = e.getCause();
        if (e2 instanceof InterruptedException || e2 instanceof InterruptedIOException)
          throw new ManifoldCFException(e2.getMessage(),e2,ManifoldCFException.INTERRUPTED);
        session = null;
        lastSessionFetch = -1L;
        // Treat this as a transient problem
        Logging.authorityConnectors.warn("Transient remote exception closing session",e);
      }
      catch (DocumentumException e)
      {
        // Base our treatment on the kind of error it is.
        if (e.getType() == DocumentumException.TYPE_SERVICEINTERRUPTION)
        {
          Logging.authorityConnectors.warn("Remote service interruption closing session",e);
        }
        else
          Logging.authorityConnectors.warn("Error closing session",e);
      }
    }
  }

  protected class GetUserAccessIDThread extends Thread
  {
    protected String strUserName;
    protected Throwable exception = null;
    protected String rval = null;
    protected AuthorizationResponse response = null;

    public GetUserAccessIDThread(String strUserName)
    {
      super();
      setDaemon(true);
      this.strUserName = strUserName;
    }

    public void run()
    {
      try
      {
        // Need the server version so we can figure out whether to try the user_login_name query
        String serverVersion = session.getServerVersion();
        boolean hasLoginNameColumn = (serverVersion.compareTo("5.3.") >= 0);

        IDocumentumObject object = null;
        try
        {
          if (hasLoginNameColumn)
            object = getObjectByQualification("dm_user where "+insensitiveMatch(caseInsensitive,"user_login_name",strUserName));
          if (!object.exists())
            object = getObjectByQualification("dm_user where "+insensitiveMatch(caseInsensitive,"user_os_name",strUserName));
          if (!object.exists())
          {
            if (Logging.authorityConnectors.isDebugEnabled())
              Logging.authorityConnectors.debug("DCTM: No user found for username '" + strUserName + "'");
            response = userNotFoundResponse;
            return;
          }

          if (object.getUserState() != 0)
          {
            if (Logging.authorityConnectors.isDebugEnabled())
              Logging.authorityConnectors.debug("DCTM: User found for username '" + strUserName + "' but the account is not active.");
            response = userUnauthorizedResponse;
            return;
          }

          rval = object.getUserName();

        }
        finally
        {
          if (object != null)
            object.release();
        }


      }
      catch (Throwable e)
      {
        this.exception = e;
      }
    }

    public Throwable getException()
    {
      return exception;
    }

    public String getUserID()
    {
      return rval;
    }

    public AuthorizationResponse getResponse()
    {
      return response;
    }
  }

  protected class GetAccessTokensThread extends Thread
  {
    protected String strDQL;
    protected ArrayList list;
    protected Throwable exception = null;

    public GetAccessTokensThread(String strDQL, ArrayList list)
    {
      super();
      setDaemon(true);
      this.strDQL = strDQL;
      this.list = list;
    }

    public void run()
    {
      try
      {
        IDocumentumResult result = session.performDQLQuery(strDQL);
        try
        {
          if (Logging.authorityConnectors.isDebugEnabled())
            Logging.authorityConnectors.debug("DCTM: Collection returned.");
          while (result.isValidRow())
          {
            String strObjectName = result.getStringValue("object_name");
            String strOwnerName = result.getStringValue("owner_name");
            String strFullTokenName = docbaseName + ":" + strOwnerName + "." + strObjectName;
            list.add(strFullTokenName);

            if (Logging.authorityConnectors.isDebugEnabled())
              Logging.authorityConnectors.debug("DCTM: ACL being added: " + strFullTokenName);

            result.nextRow();

          }
        }
        finally
        {
          result.close();
        }


      }
      catch (Throwable e)
      {
        this.exception = e;
      }
    }

    public Throwable getException()
    {
      return exception;
    }
  }

  /** Obtain the access tokens for a given user name.
  *@param strUserNamePassedIn is the user name or identifier.
  *@return the response tokens (according to the current authority).
  * (Should throws an exception only when a condition cannot be properly described within the authorization response object.)
  */
  @Override
  public AuthorizationResponse getAuthorizationResponse(String strUserNamePassedIn)
    throws ManifoldCFException
  {

    if (Logging.authorityConnectors.isDebugEnabled())
      Logging.authorityConnectors.debug("DCTM: Inside AuthorityConnector.getAuthorizationResponse for user '"+strUserNamePassedIn+"'");

    // Construct a cache description object
    ICacheDescription objectDescription = new AuthorizationResponseDescription(strUserNamePassedIn,docbaseName,userName,password,
      domain,caseInsensitive,useSystemAcls,responseLifetime,LRUsize);
    
    // Enter the cache
    ICacheHandle ch = cacheManager.enterCache(new ICacheDescription[]{objectDescription},null,null);
    try
    {
      ICacheCreateHandle createHandle = cacheManager.enterCreateSection(ch);
      try
      {
        // Lookup the object
        AuthorizationResponse response = (AuthorizationResponse)cacheManager.lookupObject(createHandle,objectDescription);
        if (response != null)
          return response;
        // Create the object.
        response = getAuthorizationResponseUncached(strUserNamePassedIn);
        // Save it in the cache
        cacheManager.saveObject(createHandle,objectDescription,response);
        // And return it...
        return response;
      }
      finally
      {
        cacheManager.leaveCreateSection(createHandle);
      }
    }
    finally
    {
      cacheManager.leaveCache(ch);
    }
  }
  
  /** Uncached get response method. */
  protected AuthorizationResponse getAuthorizationResponseUncached(String strUserNamePassedIn)
    throws ManifoldCFException
  {
    if (Logging.authorityConnectors.isDebugEnabled())
      Logging.authorityConnectors.debug("DCTM: Inside AuthorityConnector.getAuthorizationResponseUncached for user '"+strUserNamePassedIn+"'");

    try
    {
      String strUserName;

      // Strip off domain from username passed in
      int intDomainLoc = strUserNamePassedIn.indexOf("@");
      if (intDomainLoc > 1)
      {
        strUserName = strUserNamePassedIn.substring(0, intDomainLoc);
      }
      else
      {
        strUserName = strUserNamePassedIn;
      }

      String strAccessToken;
      while (true)
      {
        boolean noSession = (session==null);
        getSession();
        GetUserAccessIDThread t = new GetUserAccessIDThread(strUserName);
        try
        {
          t.start();
          t.join();
          Throwable thr = t.getException();
          if (thr != null)
          {
            if (thr instanceof RemoteException)
              throw (RemoteException)thr;
            else if (thr instanceof DocumentumException)
              throw (DocumentumException)thr;
            else if (thr instanceof RuntimeException)
              throw (RuntimeException)thr;
            else
              throw (Error)thr;
          }
          if (t.getResponse() != null)
            return t.getResponse();
          strAccessToken = t.getUserID();
          // Exit out of retry loop
          break;
        }
        catch (InterruptedException e)
        {
          t.interrupt();
          throw new ManifoldCFException("Interrupted: "+e.getMessage(),e,ManifoldCFException.INTERRUPTED);
        }
        catch (RemoteException e)
        {
          Throwable e2 = e.getCause();
          if (e2 instanceof InterruptedException || e2 instanceof InterruptedIOException)
            throw new ManifoldCFException(e2.getMessage(),e2,ManifoldCFException.INTERRUPTED);
          if (noSession)
          {
            Logging.authorityConnectors.warn("DCTM: Transient error checking authorization: "+e.getMessage(),e);
            return unreachableResponse;
          }
          session = null;
          lastSessionFetch = -1L;
          // Go back around again
        }
      }


      // String strDQL = "SELECT DISTINCT A.object_name FROM dm_acl A
      // WHERE (any (A.r_accessor_name = '" + strAccessToken + "' AND
      // A.r_accessor_permit > 1) OR ANY (A.r_accessor_name in (SELECT
      // G.group_name FROM dm_group G WHERE ANY G.i_all_users_names = '" +
      // strAccessToken + "') AND A.r_accessor_permit > 1)) AND '" +
      // strAccessToken + "' In (SELECT U.user_name FROM dm_user U WHERE
      // U.user_state=0)";
      String strDQL = "SELECT DISTINCT A.owner_name, A.object_name FROM dm_acl A " + " WHERE ";
      if (!useSystemAcls)
        strDQL += "A.object_name NOT LIKE 'dm_%' AND (";
      strDQL += "(any (A.r_accessor_name IN ('" + strAccessToken + "', 'dm_world') AND r_accessor_permit>2) "
      + " OR (any (A.r_accessor_name='dm_owner' AND A.r_accessor_permit>2) AND A.owner_name=" + quoteDQLString(strAccessToken) + ")"
      + " OR (ANY (A.r_accessor_name in (SELECT G.group_name FROM dm_group G WHERE ANY G.i_all_users_names = " + quoteDQLString(strAccessToken) + ")"
      + " AND r_accessor_permit>2))"
      + ")";
      if (!useSystemAcls)
        strDQL += ")";

      if (Logging.authorityConnectors.isDebugEnabled())
        Logging.authorityConnectors.debug("DCTM: About to execute query= (" + strDQL + ")");

      while (true)
      {
        boolean noSession = (session==null);
        getSession();
        ArrayList list =  new ArrayList();
        GetAccessTokensThread t = new GetAccessTokensThread(strDQL,list);
        try
        {
          t.start();
          t.join();
          Throwable thr = t.getException();
          if (thr != null)
          {
            if (thr instanceof RemoteException)
              throw (RemoteException)thr;
            else if (thr instanceof DocumentumException)
              throw (DocumentumException)thr;
            else if (thr instanceof RuntimeException)
              throw (RuntimeException)thr;
            else
              throw (Error)thr;
          }
          Logging.authorityConnectors.debug("DCTM: Done processing authorization query");

          String[] strArrayRetVal = new String[list.size()];

          int intObjectIdIndex = 0;

          while (intObjectIdIndex < strArrayRetVal.length)
          {
            strArrayRetVal[intObjectIdIndex] = (String)list.get(intObjectIdIndex);
            intObjectIdIndex++;
          }
          // Break out of retry loop and return
          return new AuthorizationResponse(strArrayRetVal,AuthorizationResponse.RESPONSE_OK);
        }
        catch (InterruptedException e)
        {
          t.interrupt();
          throw new ManifoldCFException("Interrupted: "+e.getMessage(),e,ManifoldCFException.INTERRUPTED);
        }
        catch (RemoteException e)
        {
          Throwable e2 = e.getCause();
          if (e2 instanceof InterruptedException || e2 instanceof InterruptedIOException)
            throw new ManifoldCFException(e2.getMessage(),e2,ManifoldCFException.INTERRUPTED);
          if (noSession)
          {
            Logging.authorityConnectors.warn("DCTM: Transient error checking authorization: "+e.getMessage(),e);
            return unreachableResponse;
          }
          session = null;
          lastSessionFetch = -1L;
          // Go back around again
        }
      }
    }
    catch (DocumentumException e)
    {

      if (e.getType() == DocumentumException.TYPE_SERVICEINTERRUPTION)
      {
        Logging.authorityConnectors.warn("DCTM: Transient error checking authorization: "+e.getMessage(),e);
        // Transient: Treat as if user does not exist, not like credentials invalid.
        return unreachableResponse;
      }
      throw new ManifoldCFException(e.getMessage(),e);
    }
  }

  /** Obtain the default access tokens for a given user name.
  *@param userName is the user name or identifier.
  *@return the default response tokens, presuming that the connect method fails.
  */
  @Override
  public AuthorizationResponse getDefaultAuthorizationResponse(String userName)
  {
    return unreachableResponse;
  }

  protected static String insensitiveMatch(boolean insensitive, String field, String value)
  {
    StringBuilder sb = new StringBuilder();
    if (insensitive)
      sb.append("upper(").append(field).append(")");
    else
      sb.append(field);
    sb.append("=");
    if (insensitive)
      sb.append(quoteDQLString(value.toUpperCase()));
    else
      sb.append(quoteDQLString(value));
    return sb.toString();
  }

  protected static String quoteDQLString(String value)
  {
    StringBuilder sb = new StringBuilder("'");
    int i = 0;
    while (i < value.length())
    {
      char x = value.charAt(i++);
      if (x == '\'')
        sb.append(x);
      sb.append(x);
    }
    sb.append("'");
    return sb.toString();
  }

  /** Test the connection.  Returns a string describing the connection integrity.
  *@return the connection's status as a displayable string.
  */
  @Override
  public String check()
    throws ManifoldCFException
  {
    try
    {
      try
      {
        checkConnection();
        return super.check();
      }
      catch (DocumentumException e)
      {
        // Base our treatment on the kind of error it is.
        if (e.getType() == DocumentumException.TYPE_SERVICEINTERRUPTION)
          return "Connection temporarily failed: "+e.getMessage();
        else
          return "Connection failed: "+e.getMessage();
      }
    }
    catch (ManifoldCFException e)
    {
      return "Connection failed: "+e.getMessage();
    }

  }


  @Override
  public void connect(ConfigParams configParams)
  {
    super.connect(configParams);

    docbaseName = configParams.getParameter(CONFIG_PARAM_DOCBASE);
    userName = configParams.getParameter(CONFIG_PARAM_USERNAME);
    password = configParams.getObfuscatedParameter(CONFIG_PARAM_PASSWORD);
    domain = configParams.getParameter(CONFIG_PARAM_DOMAIN);
    if (domain == null || domain.length() < 1)
    {
      // Empty domain is allowed
      domain = null;
    }

    String strCaseInsensitive = configParams.getParameter(CONFIG_PARAM_CASEINSENSITIVE);
    if (strCaseInsensitive != null && strCaseInsensitive.equals("true"))
    {
      caseInsensitive = true;
    }
    else
      caseInsensitive = false;

    String strUseSystemAcls = configParams.getParameter(CONFIG_PARAM_USESYSTEMACLS);
    if (strUseSystemAcls == null || strUseSystemAcls.equals("true"))
    {
      useSystemAcls = true;
    }
    else
      useSystemAcls = false;

    cacheLifetime = configParams.getParameter(CONFIG_PARAM_CACHELIFETIME);
    if (cacheLifetime == null)
      cacheLifetime = "1";
    cacheLRUsize = configParams.getParameter(CONFIG_PARAM_CACHELRUSIZE);
    if (cacheLRUsize == null)
      cacheLRUsize = "1000";    

  }

  /** Disconnect from Documentum.
  */
  @Override
  public void disconnect()
    throws ManifoldCFException
  {
    if (session != null)
    {
      DestroySessionThread t = new DestroySessionThread();
      try
      {
        t.start();
        t.join();
        Throwable thr = t.getException();
        if (thr != null)
        {
          if (thr instanceof RemoteException)
            throw (RemoteException)thr;
          else if (thr instanceof DocumentumException)
            throw (DocumentumException)thr;
          else if (thr instanceof RuntimeException)
            throw (RuntimeException)thr;
          else
            throw (Error)thr;
        }
        session = null;
        lastSessionFetch = -1L;
      }
      catch (InterruptedException e)
      {
        t.interrupt();
        throw new ManifoldCFException("Interrupted: "+e.getMessage(),e,ManifoldCFException.INTERRUPTED);
      }
      catch (RemoteException e)
      {
        Throwable e2 = e.getCause();
        if (e2 instanceof InterruptedException || e2 instanceof InterruptedIOException)
          throw new ManifoldCFException(e2.getMessage(),e2,ManifoldCFException.INTERRUPTED);
        session = null;
        lastSessionFetch = -1L;
        // Treat this as a transient problem
        Logging.authorityConnectors.warn("DCTM: Transient remote exception closing session: "+e.getMessage(),e);
      }
      catch (DocumentumException e)
      {
        // Base our treatment on the kind of error it is.
        if (e.getType() == DocumentumException.TYPE_SERVICEINTERRUPTION)
        {
          Logging.authorityConnectors.warn("DCTM: Remote service interruption closing session: "+e.getMessage(),e);
        }
        else
          Logging.authorityConnectors.warn("DCTM: Error closing session: "+e.getMessage(),e);
      }

    }

    docbaseName = null;
    userName = null;
    password = null;
    domain = null;
    
    cacheLifetime = null;
    cacheLRUsize = null;

  }

  /** This method is periodically called for all connectors that are connected but not
  * in active use.
  */
  @Override
  public void poll()
    throws ManifoldCFException
  {
    releaseCheck();
  }

  // UI support methods.
  //
  // These support methods are involved in setting up authority connection configuration information. The configuration methods cannot assume that the
  // current authority object is connected.  That is why they receive a thread context argument.
    
  /** Output the configuration header section.
  * This method is called in the head section of the connector's configuration page.  Its purpose is to add the required tabs to the list, and to output any
  * javascript methods that might be needed by the configuration editing HTML.
  *@param threadContext is the local thread context.
  *@param out is the output to which any HTML should be sent.
  *@param parameters are the configuration parameters, as they currently exist, for this connection being configured.
  *@param tabsArray is an array of tab names.  Add to this array any tab names that are specific to the connector.
  */
  @Override
  public void outputConfigurationHeader(IThreadContext threadContext, IHTTPOutput out,
    Locale locale, ConfigParams parameters, List<String> tabsArray)
    throws ManifoldCFException, IOException
  {
    tabsArray.add(Messages.getString(locale,"DCTM.Docbase"));
    tabsArray.add(Messages.getString(locale,"DCTM.UserMapping"));
    tabsArray.add(Messages.getString(locale,"DCTM.SystemACLs"));
    tabsArray.add(Messages.getString(locale,"DCTM.Cache"));

    out.print(
"<script type=\"text/javascript\">\n"+
"<!--\n"+
"function checkConfigForSave()\n"+
"{\n"+
"  if (editconnection.docbasename.value == \"\")\n"+
"  {\n"+
"    alert(\"" + Messages.getBodyJavascriptString(locale,"DCTM.PleaseSupplyTheNameOfADocbase") + "\");\n"+
"    SelectTab(\"" + Messages.getBodyJavascriptString(locale,"DCTM.Docbase") + "\");\n"+
"    editconnection.docbasename.focus();\n"+
"    return false;\n"+
"  }\n"+
"  if (editconnection.docbaseusername.value == \"\")\n"+
"  {\n"+
"    alert(\"" + Messages.getBodyJavascriptString(locale,"DCTM.TheConnectionRequiresAValidDocumentumUserName") + "\");\n"+
"    SelectTab(\"" + Messages.getBodyJavascriptString(locale,"DCTM.Docbase") + "\");\n"+
"    editconnection.docbaseusername.focus();\n"+
"    return false;\n"+
"  }\n"+
"  if (editconnection.docbasepassword.value == \"\")\n"+
"  {\n"+
"    alert(\"" + Messages.getBodyJavascriptString(locale,"DCTM.TheConnectionRequiresTheDocumentumUsersPassword") + "\");\n"+
"    SelectTab(\"" + Messages.getBodyJavascriptString(locale,"DCTM.Docbase") + "\");\n"+
"    editconnection.docbasepassword.focus();\n"+
"    return false;\n"+
"  }\n"+
"  if (editconnection.cachelifetime.value == \"\")\n"+
"  {\n"+
"    alert(\"" + Messages.getBodyJavascriptString(locale,"DCTM.CacheLifetimeCannotBeNull") + "\");\n"+
"    SelectTab(\"" + Messages.getBodyJavascriptString(locale,"DCTM.Cache") + "\");\n"+
"    editconnection.cachelifetime.focus();\n"+
"    return false;\n"+
"  }\n"+
"  if (editconnection.cachelifetime.value != \"\" && !isInteger(editconnection.cachelifetime.value))\n"+
"  {\n"+
"    alert(\"" + Messages.getBodyJavascriptString(locale,"DCTM.CacheLifetimeMustBeAnInteger") + "\");\n"+
"    SelectTab(\"" + Messages.getBodyJavascriptString(locale,"DCTM.Cache") + "\");\n"+
"    editconnection.cachelifetime.focus();\n"+
"    return false;\n"+
"  }\n"+
"  if (editconnection.cachelrusize.value == \"\")\n"+
"  {\n"+
"    alert(\"" + Messages.getBodyJavascriptString(locale,"DCTM.CacheLRUSizeCannotBeNull") + "\");\n"+
"    SelectTab(\"" + Messages.getBodyJavascriptString(locale,"DCTM.Cache") + "\");\n"+
"    editconnection.cachelrusize.focus();\n"+
"    return false;\n"+
"  }\n"+
"  if (editconnection.cachelrusize.value != \"\" && !isInteger(editconnection.cachelrusize.value))\n"+
"  {\n"+
"    alert(\"" + Messages.getBodyJavascriptString(locale,"DCTM.CacheLRUSizeMustBeAnInteger") + "\");\n"+
"    SelectTab(\"" + Messages.getBodyJavascriptString(locale,"DCTM.Cache") + "\");\n"+
"    editconnection.cachelrusize.focus();\n"+
"    return false;\n"+
"  }\n"+
"  return true;\n"+
"}\n"+
"\n"+
"//-->\n"+
"</script>\n"
    );
  }
  
  /** Output the configuration body section.
  * This method is called in the body section of the authority connector's configuration page.  Its purpose is to present the required form elements for editing.
  * The coder can presume that the HTML that is output from this configuration will be within appropriate <html>, <body>, and <form> tags.  The name of the
  * form is "editconnection".
  *@param threadContext is the local thread context.
  *@param out is the output to which any HTML should be sent.
  *@param parameters are the configuration parameters, as they currently exist, for this connection being configured.
  *@param tabName is the current tab name.
  */
  @Override
  public void outputConfigurationBody(IThreadContext threadContext, IHTTPOutput out,
    Locale locale, ConfigParams parameters, String tabName)
    throws ManifoldCFException, IOException
  {
    String docbaseName = parameters.getParameter(org.apache.manifoldcf.crawler.authorities.DCTM.AuthorityConnector.CONFIG_PARAM_DOCBASE);
    if (docbaseName == null)
      docbaseName = "";

    String docbaseUserName = parameters.getParameter(org.apache.manifoldcf.crawler.authorities.DCTM.AuthorityConnector.CONFIG_PARAM_USERNAME);
    if (docbaseUserName == null)
      docbaseUserName = "";

    String docbasePassword = parameters.getObfuscatedParameter(org.apache.manifoldcf.crawler.authorities.DCTM.AuthorityConnector.CONFIG_PARAM_PASSWORD);
    if (docbasePassword == null)
      docbasePassword = "";

    String docbaseDomain = parameters.getParameter(org.apache.manifoldcf.crawler.authorities.DCTM.AuthorityConnector.CONFIG_PARAM_DOMAIN);
    if (docbaseDomain == null)
      docbaseDomain = "";

    String caseInsensitiveUser = parameters.getParameter(org.apache.manifoldcf.crawler.authorities.DCTM.AuthorityConnector.CONFIG_PARAM_CASEINSENSITIVE);
    if (caseInsensitiveUser == null)
      caseInsensitiveUser = "false";

    String useSystemAcls = parameters.getParameter(org.apache.manifoldcf.crawler.authorities.DCTM.AuthorityConnector.CONFIG_PARAM_USESYSTEMACLS);
    if (useSystemAcls == null)
      useSystemAcls = "true";

    String cacheLifetime = parameters.getParameter(CONFIG_PARAM_CACHELIFETIME);
    if (cacheLifetime == null)
      cacheLifetime = "1";
    
    String cacheLRUsize = parameters.getParameter(CONFIG_PARAM_CACHELRUSIZE);
    if (cacheLRUsize == null)
      cacheLRUsize = "1000";    

    // "Docbase" tab
    if (tabName.equals(Messages.getString(locale,"DCTM.Docbase")))
    {
      out.print(
"<table class=\"displaytable\">\n"+
"  <tr><td class=\"separator\" colspan=\"2\"><hr/></td></tr>\n"+
"  <tr>\n"+
"    <td class=\"description\"><nobr>" + Messages.getBodyString(locale,"DCTM.DocbaseName") + "</nobr></td>\n"+
"    <td class=\"value\"><input type=\"text\" size=\"32\" name=\"docbasename\" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(docbaseName)+"\"/></td>\n"+
"  </tr>\n"+
"  <tr>\n"+
"    <td class=\"description\"><nobr>" + Messages.getBodyString(locale,"DCTM.DocbaseUserName") + "</nobr></td>\n"+
"    <td class=\"value\"><input type=\"text\" size=\"32\" name=\"docbaseusername\" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(docbaseUserName)+"\"/></td>\n"+
"  </tr>\n"+
"  <tr>\n"+
"    <td class=\"description\"><nobr>" + Messages.getBodyString(locale,"DCTM.DocbasePassword") + "</nobr></td>\n"+
"    <td class=\"value\"><input type=\"password\" size=\"32\" name=\"docbasepassword\" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(docbasePassword)+"\"/></td>\n"+
"  </tr>\n"+
"  <tr>\n"+
"    <td class=\"description\"><nobr>" + Messages.getBodyString(locale,"DCTM.DocbaseDomain") + "</nobr></td>\n"+
"    <td class=\"value\"><input type=\"text\" size=\"32\" name=\"docbasedomain\" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(docbaseDomain)+"\"/></td>\n"+
"  </tr>\n"+
"</table>\n"
      );
    }
    else
    {
      // Hiddens for "Docbase" tab
      out.print(
"<input type=\"hidden\" name=\"docbasename\" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(docbaseName)+"\"/>\n"+
"<input type=\"hidden\" name=\"docbaseusername\" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(docbaseUserName)+"\"/>\n"+
"<input type=\"hidden\" name=\"docbasepassword\" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(docbasePassword)+"\"/>\n"+
"<input type=\"hidden\" name=\"docbasedomain\" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(docbaseDomain)+"\"/>\n"
      );
    }

    // "User Mapping" tab
    if (tabName.equals(Messages.getString(locale,"DCTM.UserMapping")))
    {
      out.print(
"<table class=\"displaytable\">\n"+
"  <tr><td class=\"separator\" colspan=\"2\"><hr/></td></tr>\n"+
"  <tr>\n"+
"    <td class=\"description\"><nobr>" + Messages.getBodyString(locale,"DCTM.AuthenticationUsernameMatching") + "</nobr></td>\n"+
"    <td class=\"value\">\n"+
"      <table class=\"displaytable\">\n"+
"        <tr>\n"+
"          <td class=\"description\"><input name=\"usernamecaseinsensitive\" type=\"radio\" value=\"true\" "+((caseInsensitiveUser.equals("true"))?"checked=\"true\"":"")+" /></td>\n"+
"          <td class=\"value\"><nobr>" + Messages.getBodyString(locale,"DCTM.CaseInsensitive") + "</nobr></td>\n"+
"        </tr>\n"+
"        <tr>\n"+
"          <td class=\"description\"><input name=\"usernamecaseinsensitive\" type=\"radio\" value=\"false\" "+((!caseInsensitiveUser.equals("true"))?"checked=\"true\"":"")+" /></td>\n"+
"          <td class=\"value\"><nobr>" + Messages.getBodyString(locale,"DCTM.CaseSensitive") + "</nobr></td>\n"+
"        </tr>\n"+
"      </table>\n"+
"    </td>\n"+
"  </tr>\n"+
"</table>\n"
      );
    }
    else
    {
      // Hiddens for "User Mapping" tab
      out.print(
"<input type=\"hidden\" name=\"usernamecaseinsensitive\" value=\""+caseInsensitiveUser+"\"/>\n"
      );
    }

    // "System ACLs" tab
    if (tabName.equals(Messages.getString(locale,"DCTM.SystemACLs")))
    {
      out.print(
"<table class=\"displaytable\">\n"+
"  <tr><td class=\"separator\" colspan=\"2\"><hr/></td></tr>\n"+
"  <tr>\n"+
"    <td class=\"description\"><nobr>" + Messages.getBodyString(locale,"DCTM.UseSystemAcls") + "</nobr></td>\n"+
"    <td class=\"value\">\n"+
"      <table class=\"displaytable\">\n"+
"        <tr>\n"+
"          <td class=\"description\"><input name=\"usesystemacls\" type=\"radio\" value=\"true\" "+((useSystemAcls.equals("true"))?"checked=\"true\"":"")+" /></td>\n"+
"          <td class=\"value\"><nobr>" + Messages.getBodyString(locale,"DCTM.UseSystemAcls") + "</nobr></td>\n"+
"        </tr>\n"+
"        <tr>\n"+
"          <td class=\"description\"><input name=\"usesystemacls\" type=\"radio\" value=\"false\" "+((!useSystemAcls.equals("true"))?"checked=\"true\"":"")+" /></td>\n"+
"          <td class=\"value\"><nobr>" + Messages.getBodyString(locale,"DCTM.DontUseSystemAcls") + "</nobr></td>\n"+
"        </tr>\n"+
"      </table>\n"+
"    </td>\n"+
"  </tr>\n"+
"</table>\n"
      );
    }
    else
    {
      // Hiddens for "System ACLs" tab
      out.print(
"<input type=\"hidden\" name=\"usesystemacls\" value=\""+useSystemAcls+"\"/>\n"
      );
    }
    
    // "Cache" tab
    if(tabName.equals(Messages.getString(locale,"DCTM.Cache")))
    {
      out.print(
"<table class=\"displaytable\">\n"+
"  <tr><td class=\"separator\" colspan=\"2\"><hr/></td></tr>\n"+
"  <tr>\n"+
"    <td class=\"description\"><nobr>" + Messages.getBodyString(locale,"DCTM.CacheLifetime") + "</nobr></td>\n"+
"    <td class=\"value\"><input type=\"text\" size=\"5\" name=\"cachelifetime\" value=\"" + org.apache.manifoldcf.ui.util.Encoder.attributeEscape(cacheLifetime) + "\"/> " + Messages.getBodyString(locale,"DCTM.minutes") + "</td>\n"+
"  </tr>\n"+
"  <tr>\n"+
"    <td class=\"description\"><nobr>" + Messages.getBodyString(locale,"DCTM.CacheLRUSize") + "</nobr></td>\n"+
"    <td class=\"value\"><input type=\"text\" size=\"5\" name=\"cachelrusize\" value=\"" + org.apache.manifoldcf.ui.util.Encoder.attributeEscape(cacheLRUsize) + "\"/></td>\n"+
"  </tr>\n"+
"</table>\n"
      );
    }
    else
    {
      // Hiddens for "Cache" tab
      out.print(
"<input type=\"hidden\" name=\"cachelifetime\" value=\"" + org.apache.manifoldcf.ui.util.Encoder.attributeEscape(cacheLifetime) + "\"/>\n"+
"<input type=\"hidden\" name=\"cachelrusize\" value=\"" + org.apache.manifoldcf.ui.util.Encoder.attributeEscape(cacheLRUsize) + "\"/>\n"
      );
    }
  }
  
  /** Process a configuration post.
  * This method is called at the start of the authority connector's configuration page, whenever there is a possibility that form data for a connection has been
  * posted.  Its purpose is to gather form information and modify the configuration parameters accordingly.
  * The name of the posted form is "editconnection".
  *@param threadContext is the local thread context.
  *@param variableContext is the set of variables available from the post, including binary file post information.
  *@param parameters are the configuration parameters, as they currently exist, for this connection being configured.
  *@return null if all is well, or a string error message if there is an error that should prevent saving of the connection (and cause a redirection to an error page).
  */
  @Override
  public String processConfigurationPost(IThreadContext threadContext, IPostParameters variableContext,
    Locale locale, ConfigParams parameters)
    throws ManifoldCFException
  {
    String docbaseName = variableContext.getParameter("docbasename");
    if (docbaseName != null)
      parameters.setParameter(org.apache.manifoldcf.crawler.authorities.DCTM.AuthorityConnector.CONFIG_PARAM_DOCBASE,docbaseName);
	
    String docbaseUserName = variableContext.getParameter("docbaseusername");
    if (docbaseUserName != null)
      parameters.setParameter(org.apache.manifoldcf.crawler.authorities.DCTM.AuthorityConnector.CONFIG_PARAM_USERNAME,docbaseUserName);
	
    String docbasePassword = variableContext.getParameter("docbasepassword");
    if (docbasePassword != null)
      parameters.setObfuscatedParameter(org.apache.manifoldcf.crawler.authorities.DCTM.AuthorityConnector.CONFIG_PARAM_PASSWORD,docbasePassword);
	
    String docbaseDomain = variableContext.getParameter("docbasedomain");
    if (docbaseDomain != null)
      parameters.setParameter(org.apache.manifoldcf.crawler.authorities.DCTM.AuthorityConnector.CONFIG_PARAM_DOMAIN,docbaseDomain);

    String caseInsensitiveUser = variableContext.getParameter("usernamecaseinsensitive");
    if (caseInsensitiveUser != null)
      parameters.setParameter(org.apache.manifoldcf.crawler.authorities.DCTM.AuthorityConnector.CONFIG_PARAM_CASEINSENSITIVE,caseInsensitiveUser);

    String useSystemAcls = variableContext.getParameter("usesystemacls");
    if (useSystemAcls != null)
      parameters.setParameter(org.apache.manifoldcf.crawler.authorities.DCTM.AuthorityConnector.CONFIG_PARAM_USESYSTEMACLS,useSystemAcls);
    
    String cacheLifetime = variableContext.getParameter("cachelifetime");
    if (cacheLifetime != null)
      parameters.setParameter(CONFIG_PARAM_CACHELIFETIME,cacheLifetime);

    String cacheLRUsize = variableContext.getParameter("cachelrusize");
    if (cacheLRUsize != null)
      parameters.setParameter(CONFIG_PARAM_CACHELRUSIZE,cacheLRUsize);

    return null;
  }
  
  /** View configuration.
  * This method is called in the body section of the authority connector's view configuration page.  Its purpose is to present the connection information to the user.
  * The coder can presume that the HTML that is output from this configuration will be within appropriate <html> and <body> tags.
  *@param threadContext is the local thread context.
  *@param out is the output to which any HTML should be sent.
  *@param parameters are the configuration parameters, as they currently exist, for this connection being configured.
  */
  @Override
  public void viewConfiguration(IThreadContext threadContext, IHTTPOutput out,
    Locale locale, ConfigParams parameters)
    throws ManifoldCFException, IOException
  {
    out.print(
"<table class=\"displaytable\">\n"+
"  <tr>\n"+
"    <td class=\"description\" colspan=\"1\"><nobr>" + Messages.getBodyString(locale,"DCTM.Parameters") + "</nobr></td>\n"+
"    <td class=\"value\" colspan=\"3\">\n"
    );
    Iterator iter = parameters.listParameters();
    while (iter.hasNext())
    {
      String param = (String)iter.next();
      String value = parameters.getParameter(param);
      if (param.length() >= "password".length() && param.substring(param.length()-"password".length()).equalsIgnoreCase("password"))
      {
        out.print(
"      <nobr>"+org.apache.manifoldcf.ui.util.Encoder.bodyEscape(param)+"=********</nobr><br/>\n"
        );
      }
      else if (param.length() >="keystore".length() && param.substring(param.length()-"keystore".length()).equalsIgnoreCase("keystore"))
      {
        IKeystoreManager kmanager = KeystoreManagerFactory.make("",value);
        out.print(
"      <nobr>"+org.apache.manifoldcf.ui.util.Encoder.bodyEscape(param)+"=&lt;"+Integer.toString(kmanager.getContents().length)+" " + Messages.getBodyString(locale,"DCTM.certificate") + "&gt;</nobr><br/>\n"
        );
      }
      else
      {
        out.print(
"      <nobr>"+org.apache.manifoldcf.ui.util.Encoder.bodyEscape(param)+"="+org.apache.manifoldcf.ui.util.Encoder.bodyEscape(value)+"</nobr><br/>\n"
        );
      }
    }
    out.print(
"    </td>\n"+
"  </tr>\n"+
"</table>\n"
    );
  }

  protected static StringSet emptyStringSet = new StringSet();

  /** This is the cache object descriptor for cached access tokens from
  * this connector.
  */
  protected static class AuthorizationResponseDescription extends org.apache.manifoldcf.core.cachemanager.BaseDescription
  {
    // The parameters upon which the cached results are based.
    protected String userName;
    protected String docbaseName;
    protected String adminUserName;
    protected String adminPassword;
    protected String domain;
    protected boolean caseInsensitive;
    protected boolean useSystemACLs;
    /** The expiration time */
    protected long expirationTime = -1;
    /** The response lifetime */
    protected long responseLifetime;
    
    /** Constructor. */
    public AuthorizationResponseDescription(String userName, String docbaseName,
      String adminUserName, String adminPassword, String domain,
      boolean caseInsensitive, boolean useSystemACLs,
      long responseLifetime, int LRUsize)
    {
      super("DocumentumDirectoryAuthority",LRUsize);
      this.userName = userName;
      this.docbaseName = docbaseName;
      this.adminUserName = adminUserName;
      this.adminPassword = adminPassword;
      this.domain = domain;
      this.caseInsensitive = caseInsensitive;
      this.useSystemACLs = useSystemACLs;
      this.responseLifetime = responseLifetime;
    }

    /** Return the invalidation keys for this object. */
    public StringSet getObjectKeys()
    {
      return emptyStringSet;
    }

    /** Get the critical section name, used for synchronizing the creation of the object */
    public String getCriticalSectionName()
    {
      return getClass().getName() + "-" + userName + "-" + docbaseName +
        "-" + adminUserName + "-" + adminPassword + "-" + ((domain==null)?"NULL":domain) + "-" +
        (caseInsensitive?"true":"false") + "-" + (useSystemACLs?"true":"false");
    }

    /** Return the object expiration interval */
    public long getObjectExpirationTime(long currentTime)
    {
      if (expirationTime == -1)
        expirationTime = currentTime + responseLifetime;
      return expirationTime;
    }

    public int hashCode()
    {
      return userName.hashCode() + docbaseName.hashCode() + adminUserName.hashCode() +
        adminPassword.hashCode() + ((domain==null)?0:domain.hashCode()) +
        (caseInsensitive?1:0) + (useSystemACLs?1:0);
    }
    
    public boolean equals(Object o)
    {
      if (!(o instanceof AuthorizationResponseDescription))
        return false;
      AuthorizationResponseDescription ard = (AuthorizationResponseDescription)o;
      return ard.userName.equals(userName) && ard.docbaseName.equals(docbaseName) &&
        ard.adminUserName.equals(adminUserName) && ard.adminPassword.equals(adminPassword) &&
        ((ard.domain==null||domain==null)?(ard.domain == domain):(ard.domain.equals(domain))) &&
        ard.caseInsensitive == caseInsensitive && ard.useSystemACLs == useSystemACLs;
    }
    
  }

}
