<commit_before>/*
 * $Id$
 */
package org.xins.util.service.ldap;

import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.directory.InitialDirContext;
import org.xins.util.MandatoryArgumentChecker;
import org.xins.util.service.CallFailedException;
import org.xins.util.service.CallResult;
import org.xins.util.service.Descriptor;
import org.xins.util.service.ServiceCaller;
import org.xins.util.service.ServiceDescriptor;

/**
 * LDAP service caller.
 *
 * @version $Revision$ $Date$
 * @author <NAME> (<a href="mailto:<EMAIL>"><EMAIL></a>)
 *
 * @since XINS 0.115
 */
public final class LDAPServiceCaller extends ServiceCaller {

   //-------------------------------------------------------------------------
   // Class fields
   //-------------------------------------------------------------------------

   /**
    * Constant representing the <em>none</em> authentication method.
    */
   public static final AuthenticationMethod NO_AUTHENTICATION = new AuthenticationMethod("none");

   /**
    * Constant representing the <em>simple</em> authentication method.
    */
   public static final AuthenticationMethod SIMPLE_AUTHENTICATION = new AuthenticationMethod("simple");

   /**
    * The initial context factory.
    */
   private static final String INITIAL_CONTEXT_FACTORY = "com.sun.jndi.ldap.LdapCtxFactory";


   //-------------------------------------------------------------------------
   // Class functions
   //-------------------------------------------------------------------------

   //-------------------------------------------------------------------------
   // Constructors
   //-------------------------------------------------------------------------

   /**
    * Constructs a new <code>LDAPServiceCaller</code> object.
    *
    * @param descriptor
    *    the descriptor of the service, cannot be <code>null</code>.
    *
    * @throws IllegalArgumentException
    *    if <code>descriptor == null</code>.
    */
   public LDAPServiceCaller(Descriptor descriptor)
   throws IllegalArgumentException {
      super(descriptor);
   }


   //-------------------------------------------------------------------------
   // Fields
   //-------------------------------------------------------------------------

   //-------------------------------------------------------------------------
   // Methods
   //-------------------------------------------------------------------------

   /**
    * Performs the specified LDAP query using the specified authentication
    * details. If this succeeds with one of the targets, then a {@link Result}
    * object is returned. Otherwise, if none of the targets could successfully
    * be called, a {@link CallFailedException} is thrown.
    *
    * @param authenticationDetails
    *    the authentication details, or <code>null</code> if no authentication
    *    details should be sent down.
    *
    * @param query
    *    the query to execute, or <code>null</code> if only a connection
    *    should be made.
    *
    * @return
    *    the result of the call, cannot be <code>null</code>.
    *
    * @throws CallFailedException
    *    if the call failed.
    */
   public Result call(AuthenticationDetails authenticationDetails,
                      Query                 query)
   throws CallFailedException {

      // Construct a Request object
      Request request = new Request(authenticationDetails, query);

      // Perform the call
      CallResult callResult = doCall(request);

      // Return the result
      return (Result) callResult.getResult();
   }

   protected Object doCallImpl(ServiceDescriptor target,
                               Object            subject)
   throws Throwable {

      // Convert subject to a Request object
      Request request = (Request) subject;

      InitialDirContext context = authenticate(target, request._authenticationDetails);

      return null; // TODO
   }

   private InitialDirContext authenticate(ServiceDescriptor     target,
                                          AuthenticationDetails authenticationDetails)
   throws IllegalArgumentException, NamingException {

      // Check preconditions
      MandatoryArgumentChecker.check("target",                target,
                                     "authenticationDetails", authenticationDetails);

      // Determine what location to connect to
      String url = target.getURL();

      // TODO: Time-out

      // Initialize connection settings
      Hashtable env = new Hashtable();
      env.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
      env.put(Context.PROVIDER_URL,            url);
      env.put(Context.SECURITY_AUTHENTICATION, authenticationDetails.getMethod().getName());
      env.put(Context.SECURITY_PRINCIPAL,      authenticationDetails.getPrincipal());
      env.put(Context.SECURITY_CREDENTIALS,    authenticationDetails.getCredentials());

      // Connect
      return new InitialDirContext(env);
   }


   //-------------------------------------------------------------------------
   // Inner classes
   //-------------------------------------------------------------------------

   /**
    * LDAP authentication method.
    *
    * @version $Revision$ $Date$
    * @author <NAME> (<a href="mailto:<EMAIL>"><EMAIL>@FreeBSD.org</a>)
    *
    * @since XINS 0.115
    */
   public static final class AuthenticationMethod
   extends Object {

      //----------------------------------------------------------------------
      // Constructors
      //----------------------------------------------------------------------

      /**
       * Constructs a new <code>AuthenticationMethod</code> object.
       *
       * @param name
       *    the name of this authentication method, for example
       *    <code>"none"</code> or <code>"simple"</code>.
       */
      private AuthenticationMethod(String name) {
         _name = name;
      }

      //----------------------------------------------------------------------
      // Fields
      //----------------------------------------------------------------------

      /**
       * The name of this authentication method. Cannot be <code>null</code>.
       */
      private final String _name;


      //----------------------------------------------------------------------
      // Methods
      //----------------------------------------------------------------------

      /**
       * Returns the name of this authentication method. For example,
       * <code>"none"</code> or <code>"simple"</code>.
       *
       * @return
       *    the name of this authentication method, not <code>null</code>.
       */
      public String getName() {
         return _name;
      }

      public String toString() {
         return _name;
      }
   }

   /**
    * LDAP authentication details. Combines authentication method, principal
    * and credentials.
    *
    * @version $Revision$ $Date$
    * @author <NAME> (<a href="mailto:<EMAIL>"><EMAIL></a>)
    *
    * @since XINS 0.115
    */
   public static final class AuthenticationDetails
   extends Object {

      //----------------------------------------------------------------------
      // Constructors
      //----------------------------------------------------------------------

      /**
       * Constructs a new <code>AuthenticationDetails</code> object.
       *
       * @param method
       *    the authentication method, for example {@link #NO_AUTHENTICATION}
       *    or {@link #SIMPLE_AUTHENTICATION}, cannot be <code>null</code>.
       *
       * @param principal
       *    the principal, cannot be <code>null</code> unless
       *    <code>method == </code>{@link #NO_AUTHENTICATION}.
       *
       * @param credentials
       *    the credentials, can be <code>null</code>.
       *
       * @throws IllegalArgumentException
       *    if <code>method == null
       *    || (method != NO_AUTHENTICATION &amp;&amp; principal == null)
       *    || (method == NO_AUTHENTICATION &amp;&amp; principal != null)
       *    || (method == NO_AUTHENTICATION &amp;&amp; credentials != null)</code>.
       */
      public AuthenticationDetails(AuthenticationMethod method,
                                   String               principal,
                                   String               credentials) {
         // Check preconditions
         if (method == null) {
            throw new IllegalArgumentException("method == null");
         } else if (method != NO_AUTHENTICATION && principal == null) {
            throw new IllegalArgumentException("method != NO_AUTHENTICATION && principal == null");
         } else if (method == NO_AUTHENTICATION && principal != null) {
            throw new IllegalArgumentException("method == NO_AUTHENTICATION && principal != null");
         } else if (method == NO_AUTHENTICATION && credentials != null) {
            throw new IllegalArgumentException("method == NO_AUTHENTICATION && credentials != null");
         }

         // Set fields
         _method      = method;
         _principal   = principal;
         _credentials = credentials;
      }


      //----------------------------------------------------------------------
      // Fields
      //----------------------------------------------------------------------

      /**
       * The authentication method. Cannot be <code>null</code>.
       */
      private final AuthenticationMethod _method;

      /**
       * The principal. Is <code>null</code> if and only if
       * {@link #_method}<code> == </code>{@link #NO_AUTHENTICATION}.
       */
      private final String _principal;

      /**
       * The credentials. Can be <code>null</code>. This field is always
       * <code>null</code> if
       * {@link #_method}<code> == </code>{@link #NO_AUTHENTICATION}.
       */
      private final String _credentials;


      //----------------------------------------------------------------------
      // Methods
      //----------------------------------------------------------------------

      /**
       * Returns the authentication method.
       *
       * @return
       *    the authentication method, not <code>null</code>.
       */
      public final AuthenticationMethod getMethod() {
         return _method;
      }

      /**
       * Returns the principal. Is <code>null</code> if and only if
       * {@link #getMethod()}<code> == </code>{@link #NO_AUTHENTICATION}.
       *
       * @return
       *    the principal, possibly <code>null</code>.
       */
      public final String getPrincipal() {
         return _principal;
      }

      /**
       * The credentials. Can be <code>null</code>. This field is always
       * <code>null</code> if
       * {@link #getMethod()}<code> == </code>{@link #NO_AUTHENTICATION}.
       *
       * @return
       *    the credentials, possibly <code>null</code>.
       */
      public final String getCredentials() {
         return _credentials;
      }
   }

   /**
    * LDAP query.
    *
    * @version $Revision$ $Date$
    * @author <NAME> (<a href="mailto:<EMAIL>"><EMAIL></a>)
    *
    * @since XINS 0.115
    */
   public static final class Query
   extends Object {

      //----------------------------------------------------------------------
      // Constructors
      //----------------------------------------------------------------------

      //----------------------------------------------------------------------
      // Fields
      //----------------------------------------------------------------------

      //----------------------------------------------------------------------
      // Methods
      //----------------------------------------------------------------------
   }

   /**
    * LDAP search request. Combines
    * {@link LDAPServiceCaller.AuthenticationDetails authentication details}
    * and a {@link LDAPServiceCaller.Query query}.
    *
    * @version $Revision$ $Date$
    * @author <NAME> (<a href="mailto:<EMAIL>"><EMAIL></a>)
    *
    * @since XINS 0.115
    */
   private static final class Request
   extends Object {

      //----------------------------------------------------------------------
      // Constructors
      //----------------------------------------------------------------------

      /**
       * Constructs a new <code>Request</code> object.
       *
       * @param authenticationDetails
       *    the authentication details, can be <code>null</code>.
       *
       * @param query
       *    the query to be executed, can be <code>null</code>.
       */
      private Request(AuthenticationDetails authenticationDetails, Query query) {
         _authenticationDetails = authenticationDetails;
         _query                 = query;
      }


      //----------------------------------------------------------------------
      // Fields
      //----------------------------------------------------------------------

      /**
       * The authentication details. Can be <code>null</code>.
       */
      private final AuthenticationDetails _authenticationDetails;

      /**
       * The query. Can be <code>null</code>.
       */
      private final Query _query;


      //----------------------------------------------------------------------
      // Methods
      //----------------------------------------------------------------------
   }

   /**
    * LDAP search result.
    *
    * @version $Revision$ $Date$
    * @author <NAME> (<a href="mailto:<EMAIL>"><EMAIL></a>)
    *
    * @since XINS 0.115
    */
   public static final class Result
   extends Object {

      //----------------------------------------------------------------------
      // Constructors
      //----------------------------------------------------------------------

      //----------------------------------------------------------------------
      // Fields
      //----------------------------------------------------------------------

      //----------------------------------------------------------------------
      // Methods
      //----------------------------------------------------------------------
   }
}
<commit_msg>Added Javadoc comments.<commit_after>/*
 * $Id$
 */
package org.xins.util.service.ldap;

import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.directory.InitialDirContext;
import org.xins.util.MandatoryArgumentChecker;
import org.xins.util.service.CallFailedException;
import org.xins.util.service.CallResult;
import org.xins.util.service.Descriptor;
import org.xins.util.service.ServiceCaller;
import org.xins.util.service.ServiceDescriptor;

/**
 * LDAP service caller.
 *
 * @version $Revision$ $Date$
 * @author <NAME> (<a href="mailto:<EMAIL>"><EMAIL></a>)
 *
 * @since XINS 0.115
 */
public final class LDAPServiceCaller extends ServiceCaller {

   //-------------------------------------------------------------------------
   // Class fields
   //-------------------------------------------------------------------------

   /**
    * Constant representing the <em>none</em> authentication method.
    */
   public static final AuthenticationMethod NO_AUTHENTICATION = new AuthenticationMethod("none");

   /**
    * Constant representing the <em>simple</em> authentication method.
    */
   public static final AuthenticationMethod SIMPLE_AUTHENTICATION = new AuthenticationMethod("simple");

   /**
    * The initial context factory.
    */
   private static final String INITIAL_CONTEXT_FACTORY = "com.sun.jndi.ldap.LdapCtxFactory";


   //-------------------------------------------------------------------------
   // Class functions
   //-------------------------------------------------------------------------

   //-------------------------------------------------------------------------
   // Constructors
   //-------------------------------------------------------------------------

   /**
    * Constructs a new <code>LDAPServiceCaller</code> object.
    *
    * @param descriptor
    *    the descriptor of the service, cannot be <code>null</code>.
    *
    * @throws IllegalArgumentException
    *    if <code>descriptor == null</code>.
    */
   public LDAPServiceCaller(Descriptor descriptor)
   throws IllegalArgumentException {
      super(descriptor);
   }


   //-------------------------------------------------------------------------
   // Fields
   //-------------------------------------------------------------------------

   //-------------------------------------------------------------------------
   // Methods
   //-------------------------------------------------------------------------

   /**
    * Performs the specified LDAP query using the specified authentication
    * details. If this succeeds with one of the targets, then a {@link Result}
    * object is returned. Otherwise, if none of the targets could successfully
    * be called, a {@link CallFailedException} is thrown.
    *
    * @param authenticationDetails
    *    the authentication details, or <code>null</code> if no authentication
    *    details should be sent down.
    *
    * @param query
    *    the query to execute, or <code>null</code> if only a connection
    *    should be made.
    *
    * @return
    *    the result of the call, cannot be <code>null</code>.
    *
    * @throws CallFailedException
    *    if the call failed.
    */
   public Result call(AuthenticationDetails authenticationDetails,
                      Query                 query)
   throws CallFailedException {

      // Construct a Request object
      Request request = new Request(authenticationDetails, query);

      // Perform the call
      CallResult callResult = doCall(request);

      // Return the result
      return (Result) callResult.getResult();
   }

   protected Object doCallImpl(ServiceDescriptor target,
                               Object            subject)
   throws Throwable {

      // Convert subject to a Request object
      Request request = (Request) subject;

      InitialDirContext context = authenticate(target, request._authenticationDetails);

      return null; // TODO
   }

   /**
    * Attempts to authenticate with a target service, using the specified
    * authentication details.
    *
    * @param target
    *    descriptor of the target service to connect to, cannot be
    *    <code>null</code>.
    *
    * @param authenticationDetails
    *    the authentication details, cannot be <code>null</code>.
    *
    * @throws IllegalArgumentException
    *    if <code>target == null || authenticationDetails == null</code>.
    *
    * @throws NamingException
    *    if the connection failed.
    */
   private InitialDirContext authenticate(ServiceDescriptor     target,
                                          AuthenticationDetails authenticationDetails)
   throws IllegalArgumentException, NamingException {

      // Check preconditions
      MandatoryArgumentChecker.check("target",                target,
                                     "authenticationDetails", authenticationDetails);

      // Determine what location to connect to
      String url = target.getURL();

      // Initialize connection settings
      Hashtable env = new Hashtable();
      env.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
      env.put(Context.PROVIDER_URL,            url);
      env.put(Context.SECURITY_AUTHENTICATION, authenticationDetails.getMethod().getName());
      env.put(Context.SECURITY_PRINCIPAL,      authenticationDetails.getPrincipal());
      env.put(Context.SECURITY_CREDENTIALS,    authenticationDetails.getCredentials());

      // Connect
      // TODO: Connection time-out
      return new InitialDirContext(env);
   }


   //-------------------------------------------------------------------------
   // Inner classes
   //-------------------------------------------------------------------------

   /**
    * LDAP authentication method.
    *
    * @version $Revision$ $Date$
    * @author <NAME> (<a href="mailto:<EMAIL>"><EMAIL></a>)
    *
    * @since XINS 0.115
    */
   public static final class AuthenticationMethod
   extends Object {

      //----------------------------------------------------------------------
      // Constructors
      //----------------------------------------------------------------------

      /**
       * Constructs a new <code>AuthenticationMethod</code> object.
       *
       * @param name
       *    the name of this authentication method, for example
       *    <code>"none"</code> or <code>"simple"</code>.
       */
      private AuthenticationMethod(String name) {
         _name = name;
      }

      //----------------------------------------------------------------------
      // Fields
      //----------------------------------------------------------------------

      /**
       * The name of this authentication method. Cannot be <code>null</code>.
       */
      private final String _name;


      //----------------------------------------------------------------------
      // Methods
      //----------------------------------------------------------------------

      /**
       * Returns the name of this authentication method. For example,
       * <code>"none"</code> or <code>"simple"</code>.
       *
       * @return
       *    the name of this authentication method, not <code>null</code>.
       */
      public String getName() {
         return _name;
      }

      public String toString() {
         return _name;
      }
   }

   /**
    * LDAP authentication details. Combines authentication method, principal
    * and credentials.
    *
    * @version $Revision$ $Date$
    * @author <NAME> (<a href="mailto:<EMAIL>"><EMAIL>@FreeBSD.org</a>)
    *
    * @since XINS 0.115
    */
   public static final class AuthenticationDetails
   extends Object {

      //----------------------------------------------------------------------
      // Constructors
      //----------------------------------------------------------------------

      /**
       * Constructs a new <code>AuthenticationDetails</code> object.
       *
       * @param method
       *    the authentication method, for example {@link #NO_AUTHENTICATION}
       *    or {@link #SIMPLE_AUTHENTICATION}, cannot be <code>null</code>.
       *
       * @param principal
       *    the principal, cannot be <code>null</code> unless
       *    <code>method == </code>{@link #NO_AUTHENTICATION}.
       *
       * @param credentials
       *    the credentials, can be <code>null</code>.
       *
       * @throws IllegalArgumentException
       *    if <code>method == null
       *    || (method != NO_AUTHENTICATION &amp;&amp; principal == null)
       *    || (method == NO_AUTHENTICATION &amp;&amp; principal != null)
       *    || (method == NO_AUTHENTICATION &amp;&amp; credentials != null)</code>.
       */
      public AuthenticationDetails(AuthenticationMethod method,
                                   String               principal,
                                   String               credentials) {
         // Check preconditions
         if (method == null) {
            throw new IllegalArgumentException("method == null");
         } else if (method != NO_AUTHENTICATION && principal == null) {
            throw new IllegalArgumentException("method != NO_AUTHENTICATION && principal == null");
         } else if (method == NO_AUTHENTICATION && principal != null) {
            throw new IllegalArgumentException("method == NO_AUTHENTICATION && principal != null");
         } else if (method == NO_AUTHENTICATION && credentials != null) {
            throw new IllegalArgumentException("method == NO_AUTHENTICATION && credentials != null");
         }

         // Set fields
         _method      = method;
         _principal   = principal;
         _credentials = credentials;
      }


      //----------------------------------------------------------------------
      // Fields
      //----------------------------------------------------------------------

      /**
       * The authentication method. Cannot be <code>null</code>.
       */
      private final AuthenticationMethod _method;

      /**
       * The principal. Is <code>null</code> if and only if
       * {@link #_method}<code> == </code>{@link #NO_AUTHENTICATION}.
       */
      private final String _principal;

      /**
       * The credentials. Can be <code>null</code>. This field is always
       * <code>null</code> if
       * {@link #_method}<code> == </code>{@link #NO_AUTHENTICATION}.
       */
      private final String _credentials;


      //----------------------------------------------------------------------
      // Methods
      //----------------------------------------------------------------------

      /**
       * Returns the authentication method.
       *
       * @return
       *    the authentication method, not <code>null</code>.
       */
      public final AuthenticationMethod getMethod() {
         return _method;
      }

      /**
       * Returns the principal. Is <code>null</code> if and only if
       * {@link #getMethod()}<code> == </code>{@link #NO_AUTHENTICATION}.
       *
       * @return
       *    the principal, possibly <code>null</code>.
       */
      public final String getPrincipal() {
         return _principal;
      }

      /**
       * The credentials. Can be <code>null</code>. This field is always
       * <code>null</code> if
       * {@link #getMethod()}<code> == </code>{@link #NO_AUTHENTICATION}.
       *
       * @return
       *    the credentials, possibly <code>null</code>.
       */
      public final String getCredentials() {
         return _credentials;
      }
   }

   /**
    * LDAP query.
    *
    * @version $Revision$ $Date$
    * @author <NAME> (<a href="mailto:<EMAIL>"><EMAIL></a>)
    *
    * @since XINS 0.115
    */
   public static final class Query
   extends Object {

      //----------------------------------------------------------------------
      // Constructors
      //----------------------------------------------------------------------

      //----------------------------------------------------------------------
      // Fields
      //----------------------------------------------------------------------

      //----------------------------------------------------------------------
      // Methods
      //----------------------------------------------------------------------
   }

   /**
    * LDAP search request. Combines
    * {@link LDAPServiceCaller.AuthenticationDetails authentication details}
    * and a {@link LDAPServiceCaller.Query query}.
    *
    * @version $Revision$ $Date$
    * @author <NAME> (<a href="mailto:<EMAIL>"><EMAIL></a>)
    *
    * @since XINS 0.115
    */
   private static final class Request
   extends Object {

      //----------------------------------------------------------------------
      // Constructors
      //----------------------------------------------------------------------

      /**
       * Constructs a new <code>Request</code> object.
       *
       * @param authenticationDetails
       *    the authentication details, can be <code>null</code>.
       *
       * @param query
       *    the query to be executed, can be <code>null</code>.
       */
      private Request(AuthenticationDetails authenticationDetails, Query query) {
         _authenticationDetails = authenticationDetails;
         _query                 = query;
      }


      //----------------------------------------------------------------------
      // Fields
      //----------------------------------------------------------------------

      /**
       * The authentication details. Can be <code>null</code>.
       */
      private final AuthenticationDetails _authenticationDetails;

      /**
       * The query. Can be <code>null</code>.
       */
      private final Query _query;


      //----------------------------------------------------------------------
      // Methods
      //----------------------------------------------------------------------
   }

   /**
    * LDAP search result.
    *
    * @version $Revision$ $Date$
    * @author <NAME> (<a href="mailto:<EMAIL>"><EMAIL></a>)
    *
    * @since XINS 0.115
    */
   public static final class Result
   extends Object {

      //----------------------------------------------------------------------
      // Constructors
      //----------------------------------------------------------------------

      //----------------------------------------------------------------------
      // Fields
      //----------------------------------------------------------------------

      //----------------------------------------------------------------------
      // Methods
      //----------------------------------------------------------------------
   }
}

{'fraction_non_alphanumeric': 0.2979091664358903, 'fraction_numerical': 0.001661589587371919, 'mean_word_length': 1.1170306316869412, 'pattern_counts': {'":': 0, '<': 229, '<?xml version=': 0, '>': 229, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4153787', 'n_tokens_mistral': 6459, 'n_tokens_neox': 6242, 'n_words': 1617}