mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Matthew Swift
24.12.2011 629e2a74e77c39d0e173cfae168bf863c960cf36
Fix OpenDJ-38 - Maven: package examples with SDK
18 files added
1 files modified
2434 ■■■■■ changed files
opendj3/opendj-ldap-sdk-examples/.classpath 7 ●●●●● patch | view | raw | blame | history
opendj3/opendj-ldap-sdk-examples/.project 23 ●●●●● patch | view | raw | blame | history
opendj3/opendj-ldap-sdk-examples/.settings/org.eclipse.jdt.core.prefs 6 ●●●●● patch | view | raw | blame | history
opendj3/opendj-ldap-sdk-examples/.settings/org.maven.ide.eclipse.prefs 8 ●●●●● patch | view | raw | blame | history
opendj3/opendj-ldap-sdk-examples/pom.xml 111 ●●●●● patch | view | raw | blame | history
opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/modify/Main.java 164 ●●●●● patch | view | raw | blame | history
opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/modify/package-info.java 37 ●●●●● patch | view | raw | blame | history
opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/proxy/Main.java 698 ●●●●● patch | view | raw | blame | history
opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/proxy/package-info.java 35 ●●●●● patch | view | raw | blame | history
opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/search/Main.java 188 ●●●●● patch | view | raw | blame | history
opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/search/package-info.java 35 ●●●●● patch | view | raw | blame | history
opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/searchasync/Main.java 322 ●●●●● patch | view | raw | blame | history
opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/searchasync/package-info.java 36 ●●●●● patch | view | raw | blame | history
opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/server/Main.java 620 ●●●●● patch | view | raw | blame | history
opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/server/package-info.java 36 ●●●●● patch | view | raw | blame | history
opendj3/opendj-ldap-sdk-examples/src/site/site.xml 42 ●●●●● patch | view | raw | blame | history
opendj3/opendj-ldap-sdk-examples/src/site/site_fr.xml 27 ●●●●● patch | view | raw | blame | history
opendj3/opendj-ldap-sdk-examples/src/site/xdoc/index.xml 38 ●●●●● patch | view | raw | blame | history
opendj3/pom.xml 1 ●●●● patch | view | raw | blame | history
opendj3/opendj-ldap-sdk-examples/.classpath
New file
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
    <classpathentry kind="src" output="target/classes" path="src/main/java"/>
    <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
    <classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
    <classpathentry kind="output" path="target/classes"/>
</classpath>
opendj3/opendj-ldap-sdk-examples/.project
New file
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
    <name>opendj-ldap-examples</name>
    <comment></comment>
    <projects>
    </projects>
    <buildSpec>
        <buildCommand>
            <name>org.eclipse.jdt.core.javabuilder</name>
            <arguments>
            </arguments>
        </buildCommand>
        <buildCommand>
            <name>org.maven.ide.eclipse.maven2Builder</name>
            <arguments>
            </arguments>
        </buildCommand>
    </buildSpec>
    <natures>
        <nature>org.eclipse.jdt.core.javanature</nature>
        <nature>org.maven.ide.eclipse.maven2Nature</nature>
    </natures>
</projectDescription>
opendj3/opendj-ldap-sdk-examples/.settings/org.eclipse.jdt.core.prefs
New file
@@ -0,0 +1,6 @@
#Tue May 24 08:30:39 CEST 2011
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.source=1.6
opendj3/opendj-ldap-sdk-examples/.settings/org.maven.ide.eclipse.prefs
New file
@@ -0,0 +1,8 @@
#Tue May 24 08:30:38 CEST 2011
activeProfiles=
eclipse.preferences.version=1
fullBuildGoals=process-test-resources
resolveWorkspaceProjects=true
resourceFilterGoals=process-resources resources\:testResources
skipCompilerPlugin=true
version=1
opendj3/opendj-ldap-sdk-examples/pom.xml
New file
@@ -0,0 +1,111 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
  ! CDDL HEADER START
  !
  ! The contents of this file are subject to the terms of the
  ! Common Development and Distribution License, Version 1.0 only
  ! (the "License").  You may not use this file except in compliance
  ! with the License.
  !
  ! You can obtain a copy of the license at
  ! trunk/opendj3/legal-notices/CDDLv1_0.txt
  ! or http://forgerock.org/license/CDDLv1.0.html.
  ! See the License for the specific language governing permissions
  ! and limitations under the License.
  !
  ! When distributing Covered Code, include this CDDL HEADER in each
  ! file and include the License file at
  ! trunk/opendj3/legal-notices/CDDLv1_0.txt.  If applicable,
  ! add the following below this CDDL HEADER, with the fields enclosed
  ! by brackets "[]" replaced with your own identifying information:
  !      Portions Copyright [yyyy] [name of copyright owner]
  !
  ! CDDL HEADER END
  !
  !      Copyright 2011 ForgeRock AS
  !
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <artifactId>opendj-project</artifactId>
    <groupId>org.forgerock.opendj</groupId>
    <version>3.0.0-SNAPSHOT</version>
  </parent>
  <artifactId>opendj-ldap-sdk-examples</artifactId>
  <name>OpenDJ LDAP SDK Examples</name>
  <description>Examples illustrating usage of the OpenDJ LDAP SDK</description>
  <dependencies>
    <dependency>
      <groupId>org.forgerock.opendj</groupId>
      <artifactId>opendj-ldap-sdk</artifactId>
      <version>${project.version}</version>
      <scope>compile</scope>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-javadoc-plugin</artifactId>
        <configuration>
          <windowtitle>OpenDJ LDAP SDK Examples Documentation</windowtitle>
          <doctitle>OpenDJ LDAP SDK Examples Documentation</doctitle>
          <detectOfflineLinks>false</detectOfflineLinks>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-source-plugin</artifactId>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-checkstyle-plugin</artifactId>
      </plugin>
    </plugins>
  </build>
  <reporting>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-project-info-reports-plugin</artifactId>
        <reportSets>
          <reportSet>
            <reports>
              <report>mailing-list</report>
              <report>issue-tracking</report>
              <report>license</report>
              <report>scm</report>
              <report>cim</report>
              <report>distribution-management</report>
            </reports>
          </reportSet>
        </reportSets>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-javadoc-plugin</artifactId>
        <version>2.7</version>
        <configuration>
          <author>false</author>
          <quiet>true</quiet>
          <windowtitle>OpenDJ LDAP SDK Examples Documentation</windowtitle>
          <doctitle>OpenDJ LDAP SDK Examples Documentation</doctitle>
          <detectOfflineLinks>false</detectOfflineLinks>
        </configuration>
        <reportSets>
          <reportSet>
            <reports>
              <report>javadoc</report>
            </reports>
          </reportSet>
        </reportSets>
      </plugin>
    </plugins>
  </reporting>
</project>
opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/modify/Main.java
New file
@@ -0,0 +1,164 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opendj3/legal-notices/CDDLv1_0.txt
 * or http://forgerock.org/license/CDDLv1.0.html.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opendj3/legal-notices/CDDLv1_0.txt.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Copyright 2009-2010 Sun Microsystems, Inc.
 *      Portions copyright 2011 ForgeRock AS
 */
package org.forgerock.opendj.examples.modify;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import org.forgerock.opendj.ldap.*;
import org.forgerock.opendj.ldif.*;
/**
 * An example client application which applies update operations to a Directory
 * Server. The update operations will be read from an LDIF file, or stdin if no
 * filename is provided. This example takes the following command line
 * parameters (it will read from stdin if no LDIF file is provided):
 *
 * <pre>
 *  &lt;host> &lt;port> &lt;username> &lt;password> [&lt;ldifFile>]
 * </pre>
 */
public final class Main
{
  /**
   * Main method.
   *
   * @param args
   *          The command line arguments: host, port, username, password, LDIF
   *          file name containing the update operations (will use stdin if not
   *          provided).
   */
  public static void main(final String[] args)
  {
    if (args.length < 4 || args.length > 5)
    {
      System.err
          .println("Usage: host port username password [ldifFileName]");
      System.exit(1);
    }
    // Parse command line arguments.
    final String hostName = args[0];
    final int port = Integer.parseInt(args[1]);
    final String userName = args[2];
    final String password = args[3];
    // Create the LDIF reader which will either used the named file, if
    // provided, or stdin.
    InputStream ldif;
    if (args.length > 4)
    {
      try
      {
        ldif = new FileInputStream(args[4]);
      }
      catch (final FileNotFoundException e)
      {
        System.err.println(e.getMessage());
        System.exit(ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue());
        return;
      }
    }
    else
    {
      ldif = System.in;
    }
    final LDIFChangeRecordReader reader = new LDIFChangeRecordReader(
        ldif);
    // Connect and bind to the server.
    final LDAPConnectionFactory factory = new LDAPConnectionFactory(
        hostName, port);
    Connection connection = null;
    try
    {
      connection = factory.getConnection();
      connection.bind(userName, password.toCharArray());
      // Write the changes.
      final ConnectionChangeRecordWriter writer = new ConnectionChangeRecordWriter(
          connection);
      while (reader.hasNext())
      {
        ChangeRecord changeRecord = reader.readChangeRecord();
        writer.writeChangeRecord(changeRecord);
        System.err.println("Successfully modified entry "
            + changeRecord.getName().toString());
      }
    }
    catch (final ErrorResultException e)
    {
      System.err.println(e.getMessage());
      System.exit(e.getResult().getResultCode().intValue());
      return;
    }
    catch (final InterruptedException e)
    {
      System.err.println(e.getMessage());
      System.exit(ResultCode.CLIENT_SIDE_USER_CANCELLED.intValue());
      return;
    }
    catch (final IOException e)
    {
      System.err.println(e.getMessage());
      System.exit(ResultCode.CLIENT_SIDE_LOCAL_ERROR.intValue());
      return;
    }
    finally
    {
      if (connection != null)
      {
        connection.close();
      }
      try
      {
        reader.close();
      }
      catch (final IOException ignored)
      {
        // Ignore.
      }
    }
  }
  private Main()
  {
    // Not used.
  }
}
opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/modify/package-info.java
New file
@@ -0,0 +1,37 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opendj3/legal-notices/CDDLv1_0.txt
 * or http://forgerock.org/license/CDDLv1.0.html.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opendj3/legal-notices/CDDLv1_0.txt.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Copyright 2009-2010 Sun Microsystems, Inc.
 *      Portions copyright 2011 ForgeRock AS
 */
/**
 * An example client application which applies update operations to a Directory
 * Server. The update operations will be read from an LDIF file, or stdin if no
 * filename is provided.
 */
package org.forgerock.opendj.examples.modify;
opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/proxy/Main.java
New file
@@ -0,0 +1,698 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opendj3/legal-notices/CDDLv1_0.txt
 * or http://forgerock.org/license/CDDLv1.0.html.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opendj3/legal-notices/CDDLv1_0.txt.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Copyright 2009-2010 Sun Microsystems, Inc.
 *      Portions copyright 2011 ForgeRock AS
 */
package org.forgerock.opendj.examples.proxy;
import static org.forgerock.opendj.ldap.ErrorResultException.newErrorResult;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import org.forgerock.opendj.ldap.*;
import org.forgerock.opendj.ldap.controls.*;
import org.forgerock.opendj.ldap.requests.*;
import org.forgerock.opendj.ldap.responses.*;
/**
 * An LDAP load balancing proxy which forwards requests to one or more remote
 * Directory Servers. This is implementation is very simple and is only intended
 * as an example:
 * <ul>
 * <li>It does not support SSL connections
 * <li>It does not support StartTLS
 * <li>It does not support Abandon or Cancel requests
 * <li>Very basic authentication and authorization support.
 * </ul>
 * This example takes the following command line parameters:
 *
 * <pre>
 *  &lt;listenAddress> &lt;listenPort> &lt;remoteAddress1> &lt;remotePort1>
 *      [&lt;remoteAddress2> &lt;remotePort2> ...]
 * </pre>
 */
public final class Main
{
  /**
   * Proxy server connection factory implementation.
   */
  private static final class Proxy implements
      ServerConnectionFactory<LDAPClientContext, Integer>
  {
    private final class ServerConnectionImpl implements
        ServerConnection<Integer>
    {
      private abstract class AbstractRequestCompletionHandler<R extends Result,
                                                              H extends ResultHandler<? super R>>
          implements ResultHandler<R>
      {
        final H resultHandler;
        final AsynchronousConnection connection;
        AbstractRequestCompletionHandler(
            final AsynchronousConnection connection,
            final H resultHandler)
        {
          this.connection = connection;
          this.resultHandler = resultHandler;
        }
        @Override
        public final void handleErrorResult(
            final ErrorResultException error)
        {
          connection.close();
          resultHandler.handleErrorResult(error);
        }
        @Override
        public final void handleResult(final R result)
        {
          connection.close();
          resultHandler.handleResult(result);
        }
      }
      private abstract class ConnectionCompletionHandler<R extends Result>
          implements ResultHandler<AsynchronousConnection>
      {
        private final ResultHandler<? super R> resultHandler;
        ConnectionCompletionHandler(
            final ResultHandler<? super R> resultHandler)
        {
          this.resultHandler = resultHandler;
        }
        @Override
        public final void handleErrorResult(
            final ErrorResultException error)
        {
          resultHandler.handleErrorResult(error);
        }
        @Override
        public abstract void handleResult(
            AsynchronousConnection connection);
      }
      private final class RequestCompletionHandler<R extends Result>
          extends
          AbstractRequestCompletionHandler<R, ResultHandler<? super R>>
      {
        RequestCompletionHandler(
            final AsynchronousConnection connection,
            final ResultHandler<? super R> resultHandler)
        {
          super(connection, resultHandler);
        }
      }
      private final class SearchRequestCompletionHandler
          extends
          AbstractRequestCompletionHandler<Result, SearchResultHandler>
          implements SearchResultHandler
      {
        SearchRequestCompletionHandler(
            final AsynchronousConnection connection,
            final SearchResultHandler resultHandler)
        {
          super(connection, resultHandler);
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public final boolean handleEntry(final SearchResultEntry entry)
        {
          return resultHandler.handleEntry(entry);
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public final boolean handleReference(
            final SearchResultReference reference)
        {
          return resultHandler.handleReference(reference);
        }
      }
      private volatile ProxiedAuthV2RequestControl proxiedAuthControl = null;
      private ServerConnectionImpl(
          final LDAPClientContext clientContext)
      {
        // Nothing to do.
      }
      /**
       * {@inheritDoc}
       */
      @Override
      public void handleAbandon(final Integer requestContext,
          final AbandonRequest request)
          throws UnsupportedOperationException
      {
        // Not implemented.
      }
      /**
       * {@inheritDoc}
       */
      @Override
      public void handleAdd(
          final Integer requestContext,
          final AddRequest request,
          final ResultHandler<? super Result> resultHandler,
          final IntermediateResponseHandler intermediateResponseHandler)
          throws UnsupportedOperationException
      {
        addProxiedAuthControl(request);
        final ConnectionCompletionHandler<Result> outerHandler =
          new ConnectionCompletionHandler<Result>(resultHandler)
        {
          @Override
          public void handleResult(
              final AsynchronousConnection connection)
          {
            final RequestCompletionHandler<Result> innerHandler =
              new RequestCompletionHandler<Result>(connection, resultHandler);
            connection.add(request, innerHandler,
                intermediateResponseHandler);
          }
        };
        factory.getAsynchronousConnection(outerHandler);
      }
      /**
       * {@inheritDoc}
       */
      @Override
      public void handleBind(
          final Integer requestContext,
          final int version,
          final BindRequest request,
          final ResultHandler<? super BindResult> resultHandler,
          final IntermediateResponseHandler intermediateResponseHandler)
          throws UnsupportedOperationException
      {
        if (request.getAuthenticationType() != ((byte) 0x80))
        {
          // TODO: SASL authentication not implemented.
          resultHandler.handleErrorResult(newErrorResult(
              ResultCode.PROTOCOL_ERROR,
              "non-SIMPLE authentication not supported: "
                  + request.getAuthenticationType()));
        }
        else
        {
          // Authenticate using a separate bind connection pool, because we
          // don't want to change the state of the pooled connection.
          final ConnectionCompletionHandler<BindResult> outerHandler =
            new ConnectionCompletionHandler<BindResult>(resultHandler)
          {
            @Override
            public void handleResult(
                final AsynchronousConnection connection)
            {
              final ResultHandler<BindResult> innerHandler =
                new ResultHandler<BindResult>()
              {
                @Override
                public final void handleErrorResult(
                    final ErrorResultException error)
                {
                  connection.close();
                  resultHandler.handleErrorResult(error);
                }
                @Override
                public final void handleResult(final BindResult result)
                {
                  connection.close();
                  proxiedAuthControl = ProxiedAuthV2RequestControl
                      .newControl("dn:" + request.getName());
                  resultHandler.handleResult(result);
                }
              };
              connection.bind(request, innerHandler,
                  intermediateResponseHandler);
            }
          };
          proxiedAuthControl = null;
          bindFactory.getAsynchronousConnection(outerHandler);
        }
      }
      /**
       * {@inheritDoc}
       */
      @Override
      public void handleCompare(
          final Integer requestContext,
          final CompareRequest request,
          final ResultHandler<? super CompareResult> resultHandler,
          final IntermediateResponseHandler intermediateResponseHandler)
          throws UnsupportedOperationException
      {
        addProxiedAuthControl(request);
        final ConnectionCompletionHandler<CompareResult> outerHandler =
          new ConnectionCompletionHandler<CompareResult>(resultHandler)
        {
          @Override
          public void handleResult(
              final AsynchronousConnection connection)
          {
            final RequestCompletionHandler<CompareResult> innerHandler =
              new RequestCompletionHandler<CompareResult>(connection, resultHandler);
            connection.compare(request, innerHandler,
                intermediateResponseHandler);
          }
        };
        factory.getAsynchronousConnection(outerHandler);
      }
      /**
       * {@inheritDoc}
       */
      @Override
      public void handleConnectionClosed(
          final Integer requestContext, final UnbindRequest request)
      {
        // Client connection closed.
      }
      /**
       * {@inheritDoc}
       */
      @Override
      public void handleConnectionDisconnected(
          final ResultCode resultCode, final String message)
      {
        // Client disconnected by server.
      }
      /**
       * {@inheritDoc}
       */
      @Override
      public void handleConnectionError(final Throwable error)
      {
        // Client connection failed.
      }
      /**
       * {@inheritDoc}
       */
      @Override
      public void handleDelete(
          final Integer requestContext,
          final DeleteRequest request,
          final ResultHandler<? super Result> resultHandler,
          final IntermediateResponseHandler intermediateResponseHandler)
          throws UnsupportedOperationException
      {
        addProxiedAuthControl(request);
        final ConnectionCompletionHandler<Result> outerHandler =
          new ConnectionCompletionHandler<Result>(resultHandler)
        {
          @Override
          public void handleResult(
              final AsynchronousConnection connection)
          {
            final RequestCompletionHandler<Result> innerHandler =
              new RequestCompletionHandler<Result>(connection, resultHandler);
            connection.delete(request, innerHandler,
                intermediateResponseHandler);
          }
        };
        factory.getAsynchronousConnection(outerHandler);
      }
      /**
       * {@inheritDoc}
       */
      @Override
      public <R extends ExtendedResult> void handleExtendedRequest(
          final Integer requestContext,
          final ExtendedRequest<R> request,
          final ResultHandler<? super R> resultHandler,
          final IntermediateResponseHandler intermediateResponseHandler)
          throws UnsupportedOperationException
      {
        if (request.getOID().equals(CancelExtendedRequest.OID))
        {
          // TODO: not implemented.
          resultHandler.handleErrorResult(newErrorResult(
              ResultCode.PROTOCOL_ERROR,
              "Cancel extended request operation not supported"));
        }
        else if (request.getOID().equals(StartTLSExtendedRequest.OID))
        {
          // TODO: not implemented.
          resultHandler.handleErrorResult(newErrorResult(
              ResultCode.PROTOCOL_ERROR,
              "StartTLS extended request operation not supported"));
        }
        else
        {
          // Forward all other extended operations.
          addProxiedAuthControl(request);
          final ConnectionCompletionHandler<R> outerHandler =
            new ConnectionCompletionHandler<R>(resultHandler)
          {
            @Override
            public void handleResult(
                final AsynchronousConnection connection)
            {
              final RequestCompletionHandler<R> innerHandler =
                new RequestCompletionHandler<R>(connection, resultHandler);
              connection.extendedRequest(request, innerHandler,
                  intermediateResponseHandler);
            }
          };
          factory.getAsynchronousConnection(outerHandler);
        }
      }
      /**
       * {@inheritDoc}
       */
      @Override
      public void handleModify(
          final Integer requestContext,
          final ModifyRequest request,
          final ResultHandler<? super Result> resultHandler,
          final IntermediateResponseHandler intermediateResponseHandler)
          throws UnsupportedOperationException
      {
        addProxiedAuthControl(request);
        final ConnectionCompletionHandler<Result> outerHandler =
          new ConnectionCompletionHandler<Result>(resultHandler)
        {
          @Override
          public void handleResult(
              final AsynchronousConnection connection)
          {
            final RequestCompletionHandler<Result> innerHandler =
              new RequestCompletionHandler<Result>(connection, resultHandler);
            connection.modify(request, innerHandler,
                intermediateResponseHandler);
          }
        };
        factory.getAsynchronousConnection(outerHandler);
      }
      /**
       * {@inheritDoc}
       */
      @Override
      public void handleModifyDN(
          final Integer requestContext,
          final ModifyDNRequest request,
          final ResultHandler<? super Result> resultHandler,
          final IntermediateResponseHandler intermediateResponseHandler)
          throws UnsupportedOperationException
      {
        addProxiedAuthControl(request);
        final ConnectionCompletionHandler<Result> outerHandler =
          new ConnectionCompletionHandler<Result>(resultHandler)
        {
          @Override
          public void handleResult(
              final AsynchronousConnection connection)
          {
            final RequestCompletionHandler<Result> innerHandler =
              new RequestCompletionHandler<Result>(connection, resultHandler);
            connection.modifyDN(request, innerHandler,
                intermediateResponseHandler);
          }
        };
        factory.getAsynchronousConnection(outerHandler);
      }
      /**
       * {@inheritDoc}
       */
      @Override
      public void handleSearch(
          final Integer requestContext,
          final SearchRequest request,
          final SearchResultHandler resultHandler,
          final IntermediateResponseHandler intermediateResponseHandler)
          throws UnsupportedOperationException
      {
        addProxiedAuthControl(request);
        final ConnectionCompletionHandler<Result> outerHandler =
          new ConnectionCompletionHandler<Result>(resultHandler)
        {
          @Override
          public void handleResult(
              final AsynchronousConnection connection)
          {
            final SearchRequestCompletionHandler innerHandler =
              new SearchRequestCompletionHandler(connection, resultHandler);
            connection.search(request, innerHandler,
                intermediateResponseHandler);
          }
        };
        factory.getAsynchronousConnection(outerHandler);
      }
      private void addProxiedAuthControl(final Request request)
      {
        final ProxiedAuthV2RequestControl control = proxiedAuthControl;
        if (control != null)
        {
          request.addControl(control);
        }
      }
    }
    private final ConnectionFactory factory;
    private final ConnectionFactory bindFactory;
    private Proxy(final ConnectionFactory factory,
        final ConnectionFactory bindFactory)
    {
      this.factory = factory;
      this.bindFactory = bindFactory;
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public ServerConnection<Integer> handleAccept(
        final LDAPClientContext clientContext)
        throws ErrorResultException
    {
      return new ServerConnectionImpl(clientContext);
    }
  }
  /**
   * Main method.
   *
   * @param args
   *          The command line arguments: listen address, listen port, remote
   *          address1, remote port1, remote address2, remote port2, ...
   */
  public static void main(final String[] args)
  {
    if (args.length < 4 || args.length % 2 != 0)
    {
      System.err.println("Usage: listenAddress listenPort "
          + "remoteAddress1 remotePort1 remoteAddress2 remotePort2");
      System.exit(1);
    }
    // Parse command line arguments.
    final String localAddress = args[0];
    final int localPort = Integer.parseInt(args[1]);
    // Create load balancer.
    final List<ConnectionFactory> factories = new LinkedList<ConnectionFactory>();
    final List<ConnectionFactory> bindFactories = new LinkedList<ConnectionFactory>();
    for (int i = 2; i < args.length; i += 2)
    {
      final String remoteAddress = args[i];
      final int remotePort = Integer.parseInt(args[i + 1]);
      factories.add(Connections.newConnectionPool(
          new LDAPConnectionFactory(remoteAddress, remotePort),
          Integer.MAX_VALUE));
      bindFactories.add(Connections.newConnectionPool(
          new LDAPConnectionFactory(remoteAddress, remotePort),
          Integer.MAX_VALUE));
    }
    final RoundRobinLoadBalancingAlgorithm algorithm =
      new RoundRobinLoadBalancingAlgorithm(factories);
    final RoundRobinLoadBalancingAlgorithm bindAlgorithm =
      new RoundRobinLoadBalancingAlgorithm(bindFactories);
    final ConnectionFactory factory = Connections
        .newLoadBalancer(algorithm);
    final ConnectionFactory bindFactory = Connections
        .newLoadBalancer(bindAlgorithm);
    // Create listener.
    final LDAPListenerOptions options = new LDAPListenerOptions()
        .setBacklog(4096);
    LDAPListener listener = null;
    try
    {
      listener = new LDAPListener(localAddress, localPort, new Proxy(
          factory, bindFactory), options);
      System.out.println("Press any key to stop the server...");
      System.in.read();
    }
    catch (final IOException e)
    {
      System.out.println("Error listening on " + localAddress + ":"
          + localPort);
      e.printStackTrace();
    }
    finally
    {
      if (listener != null)
      {
        listener.close();
      }
    }
  }
  private Main()
  {
    // Not used.
  }
}
opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/proxy/package-info.java
New file
@@ -0,0 +1,35 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opendj3/legal-notices/CDDLv1_0.txt
 * or http://forgerock.org/license/CDDLv1.0.html.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opendj3/legal-notices/CDDLv1_0.txt.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Copyright 2009-2010 Sun Microsystems, Inc.
 *      Portions copyright 2011 ForgeRock AS
 */
/**
 * An example LDAP proxy which forwards requests to a remote Directory Server.
 */
package org.forgerock.opendj.examples.proxy;
opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/search/Main.java
New file
@@ -0,0 +1,188 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opendj3/legal-notices/CDDLv1_0.txt
 * or http://forgerock.org/license/CDDLv1.0.html.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opendj3/legal-notices/CDDLv1_0.txt.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Copyright 2009-2010 Sun Microsystems, Inc.
 *      Portions copyright 2011 ForgeRock AS
 */
package org.forgerock.opendj.examples.search;
import java.io.IOException;
import java.util.Arrays;
import org.forgerock.opendj.ldap.*;
import org.forgerock.opendj.ldap.responses.*;
import org.forgerock.opendj.ldif.*;
/**
 * An example client application which searches a Directory Server. This example
 * takes the following command line parameters:
 *
 * <pre>
 *  &lt;host> &lt;port> &lt;username> &lt;password>
 *      &lt;baseDN> &lt;scope> &lt;filter> [&lt;attibute> &lt;attribute> ...]
 * </pre>
 */
public final class Main
{
  /**
   * Main method.
   *
   * @param args
   *          The command line arguments: host, port, username, password, base
   *          DN, scope, filter, and zero or more attributes to be retrieved.
   */
  public static void main(final String[] args)
  {
    if (args.length < 7)
    {
      System.err
          .println("Usage: host port username password baseDN scope "
              + "filter [attribute ...]");
      System.exit(1);
    }
    // Parse command line arguments.
    final String hostName = args[0];
    final int port = Integer.parseInt(args[1]);
    final String userName = args[2];
    final String password = args[3];
    final String baseDN = args[4];
    final String scopeString = args[5];
    final String filter = args[6];
    String[] attributes;
    if (args.length > 7)
    {
      attributes = Arrays.copyOfRange(args, 7, args.length);
    }
    else
    {
      attributes = new String[0];
    }
    SearchScope scope;
    if (scopeString.equalsIgnoreCase("base"))
    {
      scope = SearchScope.BASE_OBJECT;
    }
    else if (scopeString.equalsIgnoreCase("one"))
    {
      scope = SearchScope.SINGLE_LEVEL;
    }
    else if (scopeString.equalsIgnoreCase("sub"))
    {
      scope = SearchScope.WHOLE_SUBTREE;
    }
    else if (scopeString.equalsIgnoreCase("subordinates"))
    {
      scope = SearchScope.SUBORDINATES;
    }
    else
    {
      System.err.println("Unknown scope: " + scopeString);
      System.exit(ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue());
      return;
    }
    // Create an LDIF writer which will write the search results to stdout.
    final LDIFEntryWriter writer = new LDIFEntryWriter(System.out);
    // Connect and bind to the server.
    final LDAPConnectionFactory factory = new LDAPConnectionFactory(
        hostName, port);
    Connection connection = null;
    try
    {
      connection = factory.getConnection();
      connection.bind(userName, password.toCharArray());
      // Read the entries and output them as LDIF.
      final ConnectionEntryReader reader = connection.search(baseDN,
          scope, filter, attributes);
      while (reader.hasNext())
      {
        if (!reader.isReference())
        {
          final SearchResultEntry entry = reader.readEntry();
          writer.writeComment("Search result entry: "
              + entry.getName().toString());
          writer.writeEntry(entry);
        }
        else
        {
          final SearchResultReference ref = reader.readReference();
          // Got a continuation reference.
          writer.writeComment("Search result reference: "
              + ref.getURIs().toString());
        }
      }
      writer.flush();
    }
    catch (final ErrorResultException e)
    {
      System.err.println(e.getMessage());
      System.exit(e.getResult().getResultCode().intValue());
      return;
    }
    catch (final ErrorResultIOException e)
    {
      System.err.println(e.getMessage());
      System
          .exit(e.getCause().getResult().getResultCode().intValue());
      return;
    }
    catch (final InterruptedException e)
    {
      System.err.println(e.getMessage());
      System.exit(ResultCode.CLIENT_SIDE_USER_CANCELLED.intValue());
      return;
    }
    catch (final IOException e)
    {
      System.err.println(e.getMessage());
      System.exit(ResultCode.CLIENT_SIDE_LOCAL_ERROR.intValue());
      return;
    }
    finally
    {
      if (connection != null)
      {
        connection.close();
      }
    }
  }
  private Main()
  {
    // Not used.
  }
}
opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/search/package-info.java
New file
@@ -0,0 +1,35 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opendj3/legal-notices/CDDLv1_0.txt
 * or http://forgerock.org/license/CDDLv1.0.html.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opendj3/legal-notices/CDDLv1_0.txt.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Copyright 2009-2010 Sun Microsystems, Inc.
 *      Portions copyright 2011 ForgeRock AS
 */
/**
 * An example client application which searches a Directory Server.
 */
package org.forgerock.opendj.examples.search;
opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/searchasync/Main.java
New file
@@ -0,0 +1,322 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opendj3/legal-notices/CDDLv1_0.txt
 * or http://forgerock.org/license/CDDLv1.0.html.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opendj3/legal-notices/CDDLv1_0.txt.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Copyright 2009-2010 Sun Microsystems, Inc.
 *      Portions copyright 2011 ForgeRock AS
 */
package org.forgerock.opendj.examples.searchasync;
import java.io.IOException;
import java.util.Arrays;
import java.util.concurrent.CountDownLatch;
import org.forgerock.opendj.ldap.*;
import org.forgerock.opendj.ldap.requests.*;
import org.forgerock.opendj.ldap.responses.*;
import org.forgerock.opendj.ldif.*;
/**
 * An example client application which searches a Directory Server using the
 * asynchronous APIs. This example takes the following command line parameters:
 *
 * <pre>
 *  &lt;host> &lt;port> &lt;username> &lt;password>
 *      &lt;baseDN> &lt;scope> &lt;filter> [&lt;attibute> &lt;attribute> ...]
 * </pre>
 */
public final class Main
{
  private static final class BindResultHandlerImpl implements
      ResultHandler<BindResult>
  {
    /**
     * {@inheritDoc}
     */
    @Override
    public void handleErrorResult(final ErrorResultException error)
    {
      System.err.println(error.getMessage());
      resultCode = error.getResult().getResultCode().intValue();
      COMPLETION_LATCH.countDown();
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public void handleResult(final BindResult result)
    {
      // Bind succeeded: initiate search.
      final SearchRequest request = Requests.newSearchRequest(baseDN,
          scope, filter, attributes);
      connection.search(request, new SearchResultHandlerImpl());
    }
  }
  private static final class ConnectResultHandlerImpl implements
      ResultHandler<AsynchronousConnection>
  {
    /**
     * {@inheritDoc}
     */
    @Override
    public void handleErrorResult(final ErrorResultException error)
    {
      System.err.println(error.getMessage());
      resultCode = error.getResult().getResultCode().intValue();
      COMPLETION_LATCH.countDown();
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public void handleResult(final AsynchronousConnection connection)
    {
      // Connect succeeded: save connection and initiate bind.
      Main.connection = connection;
      final BindRequest request = Requests.newSimpleBindRequest(
          userName, password.toCharArray());
      connection.bind(request, new BindResultHandlerImpl());
    }
  }
  private static final class SearchResultHandlerImpl implements
      SearchResultHandler
  {
    /**
     * {@inheritDoc}
     */
    @Override
    public synchronized boolean handleEntry(
        final SearchResultEntry entry)
    {
      try
      {
        WRITER.writeComment("Search result entry: "
            + entry.getName().toString());
        WRITER.writeEntry(entry);
      }
      catch (final IOException e)
      {
        System.err.println(e.getMessage());
        resultCode = ResultCode.CLIENT_SIDE_LOCAL_ERROR.intValue();
        COMPLETION_LATCH.countDown();
        return false;
      }
      return true;
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public void handleErrorResult(final ErrorResultException error)
    {
      System.err.println(error.getMessage());
      resultCode = error.getResult().getResultCode().intValue();
      COMPLETION_LATCH.countDown();
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public synchronized boolean handleReference(
        final SearchResultReference reference)
    {
      try
      {
        WRITER.writeComment("Search result reference: "
            + reference.getURIs().toString());
      }
      catch (final IOException e)
      {
        System.err.println(e.getMessage());
        resultCode = ResultCode.CLIENT_SIDE_LOCAL_ERROR.intValue();
        COMPLETION_LATCH.countDown();
        return false;
      }
      return true;
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public void handleResult(final Result result)
    {
      resultCode = result.getResultCode().intValue();
      COMPLETION_LATCH.countDown();
    }
  }
  private static final CountDownLatch COMPLETION_LATCH = new CountDownLatch(
      1);
  private static final LDIFEntryWriter WRITER = new LDIFEntryWriter(
      System.out);
  private static String userName;
  private static String password;
  private static String baseDN;
  private static SearchScope scope;
  private static String filter;
  private static String[] attributes;
  private static AsynchronousConnection connection = null;
  private static int resultCode = 0;
  /**
   * Main method.
   *
   * @param args
   *          The command line arguments: host, port, username, password, base
   *          DN, scope, filter, and zero or more attributes to be retrieved.
   */
  public static void main(final String[] args)
  {
    if (args.length < 7)
    {
      System.err
          .println("Usage: host port username password baseDN scope "
              + "filter [attribute ...]");
      System.exit(1);
    }
    // Parse command line arguments.
    final String hostName = args[0];
    final int port = Integer.parseInt(args[1]);
    userName = args[2];
    password = args[3];
    baseDN = args[4];
    final String scopeString = args[5];
    filter = args[6];
    if (args.length > 7)
    {
      attributes = Arrays.copyOfRange(args, 7, args.length);
    }
    else
    {
      attributes = new String[0];
    }
    if (scopeString.equalsIgnoreCase("base"))
    {
      scope = SearchScope.BASE_OBJECT;
    }
    else if (scopeString.equalsIgnoreCase("one"))
    {
      scope = SearchScope.SINGLE_LEVEL;
    }
    else if (scopeString.equalsIgnoreCase("sub"))
    {
      scope = SearchScope.WHOLE_SUBTREE;
    }
    else if (scopeString.equalsIgnoreCase("subordinates"))
    {
      scope = SearchScope.SUBORDINATES;
    }
    else
    {
      System.err.println("Unknown scope: " + scopeString);
      System.exit(ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue());
      return;
    }
    // Initiate the asynchronous connect, bind, and search.
    final LDAPConnectionFactory factory = new LDAPConnectionFactory(
        hostName, port);
    factory.getAsynchronousConnection(new ConnectResultHandlerImpl());
    // Await completion.
    try
    {
      COMPLETION_LATCH.await();
    }
    catch (final InterruptedException e)
    {
      System.err.println(e.getMessage());
      System.exit(ResultCode.CLIENT_SIDE_USER_CANCELLED.intValue());
      return;
    }
    try
    {
      WRITER.flush();
    }
    catch (final IOException e)
    {
      System.err.println(e.getMessage());
      System.exit(ResultCode.CLIENT_SIDE_LOCAL_ERROR.intValue());
      return;
    }
    if (connection != null)
    {
      connection.close();
    }
    System.exit(resultCode);
  }
  private Main()
  {
    // Not used.
  }
}
opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/searchasync/package-info.java
New file
@@ -0,0 +1,36 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opendj3/legal-notices/CDDLv1_0.txt
 * or http://forgerock.org/license/CDDLv1.0.html.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opendj3/legal-notices/CDDLv1_0.txt.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Copyright 2009-2010 Sun Microsystems, Inc.
 *      Portions copyright 2011 ForgeRock AS
 */
/**
 * An example client application which searches a Directory Server using the
 * asynchronous APIs.
 */
package org.forgerock.opendj.examples.searchasync;
opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/server/Main.java
New file
@@ -0,0 +1,620 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opendj3/legal-notices/CDDLv1_0.txt
 * or http://forgerock.org/license/CDDLv1.0.html.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opendj3/legal-notices/CDDLv1_0.txt.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Copyright 2009-2010 Sun Microsystems, Inc.
 *      Portions copyright 2011 ForgeRock AS
 */
package org.forgerock.opendj.examples.server;
import static org.forgerock.opendj.ldap.ErrorResultException.newErrorResult;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.NavigableMap;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.forgerock.opendj.ldap.*;
import org.forgerock.opendj.ldap.requests.*;
import org.forgerock.opendj.ldap.responses.*;
import org.forgerock.opendj.ldif.*;
/**
 * An LDAP directory server which exposes data contained in an LDIF file. This
 * is implementation is very simple and is only intended as an example:
 * <ul>
 * <li>It does not support SSL connections
 * <li>It does not support StartTLS
 * <li>It does not support Abandon or Cancel requests
 * <li>Very basic authentication and authorization support.
 * </ul>
 * This example takes the following command line parameters:
 *
 * <pre>
 *  &lt;listenAddress> &lt;listenPort> [&lt;ldifFile>]
 * </pre>
 */
public final class Main
{
  /**
   * Proxy server connection factory implementation.
   */
  private static final class Store implements
      ServerConnectionFactory<LDAPClientContext, Integer>
  {
    private final class ServerConnectionImpl implements
        ServerConnection<Integer>
    {
      private ServerConnectionImpl(
          final LDAPClientContext clientContext)
      {
        // Nothing to do.
      }
      /**
       * {@inheritDoc}
       */
      @Override
      public void handleAbandon(final Integer requestContext,
          final AbandonRequest request)
          throws UnsupportedOperationException
      {
        // Not implemented.
      }
      /**
       * {@inheritDoc}
       */
      @Override
      public void handleAdd(
          final Integer requestContext,
          final AddRequest request,
          final ResultHandler<? super Result> resultHandler,
          final IntermediateResponseHandler intermediateResponseHandler)
          throws UnsupportedOperationException
      {
        // TODO: controls.
        entryLock.writeLock().lock();
        try
        {
          DN dn = request.getName();
          if (entries.containsKey(dn))
          {
            resultHandler
                .handleErrorResult(ErrorResultException
                    .newErrorResult(ResultCode.ENTRY_ALREADY_EXISTS,
                        "The entry " + dn.toString()
                            + " already exists"));
          }
          DN parent = dn.parent();
          if (!entries.containsKey(parent))
          {
            resultHandler.handleErrorResult(ErrorResultException
                .newErrorResult(ResultCode.NO_SUCH_OBJECT,
                    "The parent entry " + parent.toString()
                        + " does not exist"));
          }
          else
          {
            entries.put(dn, request);
            resultHandler.handleResult(Responses
                .newResult(ResultCode.SUCCESS));
          }
        }
        finally
        {
          entryLock.writeLock().unlock();
        }
      }
      /**
       * {@inheritDoc}
       */
      @Override
      public void handleBind(
          final Integer requestContext,
          final int version,
          final BindRequest request,
          final ResultHandler<? super BindResult> resultHandler,
          final IntermediateResponseHandler intermediateResponseHandler)
          throws UnsupportedOperationException
      {
        if (request.getAuthenticationType() != ((byte) 0x80))
        {
          // TODO: SASL authentication not implemented.
          resultHandler.handleErrorResult(newErrorResult(
              ResultCode.PROTOCOL_ERROR,
              "non-SIMPLE authentication not supported: "
                  + request.getAuthenticationType()));
        }
        else
        {
          // TODO: always succeed.
          resultHandler.handleResult(Responses
              .newBindResult(ResultCode.SUCCESS));
        }
      }
      /**
       * {@inheritDoc}
       */
      @Override
      public void handleCompare(
          final Integer requestContext,
          final CompareRequest request,
          final ResultHandler<? super CompareResult> resultHandler,
          final IntermediateResponseHandler intermediateResponseHandler)
          throws UnsupportedOperationException
      {
        // TODO:
      }
      /**
       * {@inheritDoc}
       */
      @Override
      public void handleConnectionClosed(
          final Integer requestContext, final UnbindRequest request)
      {
        // Nothing to do.
      }
      /**
       * {@inheritDoc}
       */
      @Override
      public void handleConnectionDisconnected(
          final ResultCode resultCode, final String message)
      {
        // Nothing to do.
      }
      /**
       * {@inheritDoc}
       */
      @Override
      public void handleConnectionError(final Throwable error)
      {
        // Nothing to do.
      }
      /**
       * {@inheritDoc}
       */
      @Override
      public void handleDelete(
          final Integer requestContext,
          final DeleteRequest request,
          final ResultHandler<? super Result> resultHandler,
          final IntermediateResponseHandler intermediateResponseHandler)
          throws UnsupportedOperationException
      {
        // TODO: controls.
        entryLock.writeLock().lock();
        try
        {
          // TODO: check for children.
          DN dn = request.getName();
          if (!entries.containsKey(dn))
          {
            resultHandler
                .handleErrorResult(ErrorResultException
                    .newErrorResult(ResultCode.NO_SUCH_OBJECT,
                        "The entry " + dn.toString()
                            + " does not exist"));
          }
          else
          {
            entries.remove(dn);
            resultHandler.handleResult(Responses
                .newResult(ResultCode.SUCCESS));
          }
        }
        finally
        {
          entryLock.writeLock().unlock();
        }
      }
      /**
       * {@inheritDoc}
       */
      @Override
      public <R extends ExtendedResult> void handleExtendedRequest(
          final Integer requestContext,
          final ExtendedRequest<R> request,
          final ResultHandler<? super R> resultHandler,
          final IntermediateResponseHandler intermediateResponseHandler)
          throws UnsupportedOperationException
      {
        // TODO: not implemented.
        resultHandler.handleErrorResult(newErrorResult(
            ResultCode.PROTOCOL_ERROR,
            "Extended request operation not supported"));
      }
      /**
       * {@inheritDoc}
       */
      @Override
      public void handleModify(
          final Integer requestContext,
          final ModifyRequest request,
          final ResultHandler<? super Result> resultHandler,
          final IntermediateResponseHandler intermediateResponseHandler)
          throws UnsupportedOperationException
      {
        // TODO: controls.
        // TODO: read lock is not really enough since concurrent updates may
        // still occur to the same entry.
        entryLock.readLock().lock();
        try
        {
          DN dn = request.getName();
          Entry entry = entries.get(dn);
          if (entry == null)
          {
            resultHandler
                .handleErrorResult(ErrorResultException
                    .newErrorResult(ResultCode.NO_SUCH_OBJECT,
                        "The entry " + dn.toString()
                            + " does not exist"));
          }
          Entry newEntry = new LinkedHashMapEntry(entry);
          for (Modification mod : request.getModifications())
          {
            ModificationType modType = mod.getModificationType();
            if (modType.equals(ModificationType.ADD))
            {
              // TODO: Reject empty attribute and duplicate values.
              newEntry.addAttribute(mod.getAttribute(), null);
            }
            else if (modType.equals(ModificationType.DELETE))
            {
              // TODO: Reject missing values.
              newEntry.removeAttribute(mod.getAttribute(), null);
            }
            else if (modType.equals(ModificationType.REPLACE))
            {
              newEntry.replaceAttribute(mod.getAttribute());
            }
            else
            {
              resultHandler
                  .handleErrorResult(newErrorResult(
                      ResultCode.PROTOCOL_ERROR,
                      "Modify request contains an unsupported modification type"));
              return;
            }
          }
          entries.put(dn, newEntry);
          resultHandler.handleResult(Responses
              .newResult(ResultCode.SUCCESS));
        }
        finally
        {
          entryLock.readLock().unlock();
        }
      }
      /**
       * {@inheritDoc}
       */
      @Override
      public void handleModifyDN(
          final Integer requestContext,
          final ModifyDNRequest request,
          final ResultHandler<? super Result> resultHandler,
          final IntermediateResponseHandler intermediateResponseHandler)
          throws UnsupportedOperationException
      {
        // TODO: not implemented.
        resultHandler.handleErrorResult(newErrorResult(
            ResultCode.PROTOCOL_ERROR,
            "ModifyDN request operation not supported"));
      }
      /**
       * {@inheritDoc}
       */
      @Override
      public void handleSearch(
          final Integer requestContext,
          final SearchRequest request,
          final SearchResultHandler resultHandler,
          final IntermediateResponseHandler intermediateResponseHandler)
          throws UnsupportedOperationException
      {
        // TODO: controls, limits, etc.
        entryLock.readLock().lock();
        try
        {
          DN dn = request.getName();
          Entry baseEntry = entries.get(dn);
          if (baseEntry == null)
          {
            resultHandler
                .handleErrorResult(ErrorResultException
                    .newErrorResult(ResultCode.NO_SUCH_OBJECT,
                        "The entry " + dn.toString()
                            + " does not exist"));
          }
          SearchScope scope = request.getScope();
          if (scope.equals(SearchScope.BASE_OBJECT))
          {
            sendEntry(request, resultHandler, baseEntry);
          }
          else if (scope.equals(SearchScope.SINGLE_LEVEL))
          {
            sendEntry(request, resultHandler, baseEntry);
            NavigableMap<DN, Entry> subtree = entries.tailMap(dn,
                false);
            for (Entry entry : subtree.values())
            {
              DN childDN = entry.getName();
              if (childDN.isChildOf(dn))
              {
                if (!sendEntry(request, resultHandler, entry))
                {
                  // Caller has asked to stop sending results.
                  break;
                }
              }
              else if (!childDN.isSubordinateOrEqualTo(dn))
              {
                // The remaining entries will be out of scope.
                break;
              }
            }
          }
          else if (scope.equals(SearchScope.WHOLE_SUBTREE))
          {
            NavigableMap<DN, Entry> subtree = entries.tailMap(dn);
            for (Entry entry : subtree.values())
            {
              DN childDN = entry.getName();
              if (childDN.isSubordinateOrEqualTo(dn))
              {
                if (!sendEntry(request, resultHandler, entry))
                {
                  // Caller has asked to stop sending results.
                  break;
                }
              }
              else
              {
                // The remaining entries will be out of scope.
                break;
              }
            }
          }
          else
          {
            resultHandler
                .handleErrorResult(newErrorResult(
                    ResultCode.PROTOCOL_ERROR,
                    "Search request contains an unsupported search scope"));
            return;
          }
          resultHandler.handleResult(Responses
              .newResult(ResultCode.SUCCESS));
        }
        finally
        {
          entryLock.readLock().unlock();
        }
      }
      private boolean sendEntry(SearchRequest request,
          SearchResultHandler resultHandler, Entry entry)
      {
        // TODO: check filter, strip attributes.
        return resultHandler.handleEntry(Responses
            .newSearchResultEntry(entry));
      }
    }
    private final ConcurrentSkipListMap<DN, Entry> entries;
    private final ReentrantReadWriteLock entryLock = new ReentrantReadWriteLock();
    private Store(final ConcurrentSkipListMap<DN, Entry> entries)
    {
      this.entries = entries;
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public ServerConnection<Integer> handleAccept(
        final LDAPClientContext clientContext)
        throws ErrorResultException
    {
      return new ServerConnectionImpl(clientContext);
    }
  }
  /**
   * Main method.
   *
   * @param args
   *          The command line arguments: listen address, listen port, ldifFile
   */
  public static void main(final String[] args)
  {
    if (args.length != 3)
    {
      System.err.println("Usage: listenAddress listenPort ldifFile");
      System.exit(1);
    }
    // Parse command line arguments.
    final String localAddress = args[0];
    final int localPort = Integer.parseInt(args[1]);
    // Read the LDIF.
    InputStream ldif;
    try
    {
      ldif = new FileInputStream(args[2]);
    }
    catch (final FileNotFoundException e)
    {
      System.err.println(e.getMessage());
      System.exit(ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue());
      return;
    }
    final LDIFEntryReader reader = new LDIFEntryReader(ldif);
    ConcurrentSkipListMap<DN, Entry> entries = new ConcurrentSkipListMap<DN, Entry>();
    try
    {
      while (reader.hasNext())
      {
        Entry entry = reader.readEntry();
        entries.put(entry.getName(), entry);
      }
    }
    catch (final IOException e)
    {
      System.err.println(e.getMessage());
      System.exit(ResultCode.CLIENT_SIDE_LOCAL_ERROR.intValue());
      return;
    }
    finally
    {
      try
      {
        reader.close();
      }
      catch (final IOException ignored)
      {
        // Ignore.
      }
    }
    // Quickly sanity check that every entry (except root entries) have a
    // parent.
    boolean isValid = true;
    for (DN dn : entries.keySet())
    {
      if (dn.size() > 1)
      {
        DN parent = dn.parent();
        if (!entries.containsKey(parent))
        {
          System.err.println("The entry \"" + dn.toString()
              + "\" does not have a parent");
          isValid = false;
        }
      }
    }
    if (!isValid)
    {
      System.exit(1);
    }
    // Create listener.
    final LDAPListenerOptions options = new LDAPListenerOptions()
        .setBacklog(4096);
    LDAPListener listener = null;
    try
    {
      listener = new LDAPListener(localAddress, localPort, new Store(
          entries), options);
      System.out.println("Press any key to stop the server...");
      System.in.read();
    }
    catch (final IOException e)
    {
      System.out.println("Error listening on " + localAddress + ":"
          + localPort);
      e.printStackTrace();
    }
    finally
    {
      if (listener != null)
      {
        listener.close();
      }
    }
  }
  private Main()
  {
    // Not used.
  }
}
opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/server/package-info.java
New file
@@ -0,0 +1,36 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opendj3/legal-notices/CDDLv1_0.txt
 * or http://forgerock.org/license/CDDLv1.0.html.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opendj3/legal-notices/CDDLv1_0.txt.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Copyright 2009-2010 Sun Microsystems, Inc.
 *      Portions copyright 2011 ForgeRock AS
 */
/**
 * An example LDAP data store which exposes data which is contained within an
 * LDIF file.
 */
package org.forgerock.opendj.examples.server;
opendj3/opendj-ldap-sdk-examples/src/site/site.xml
New file
@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
  ! CCPL HEADER START
  !
  ! This work is licensed under the Creative Commons
  ! Attribution-NonCommercial-NoDerivs 3.0 Unported License.
  ! To view a copy of this license, visit
  ! http://creativecommons.org/licenses/by-nc-nd/3.0/
  ! or send a letter to Creative Commons, 444 Castro Street,
  ! Suite 900, Mountain View, California, 94041, USA.
  !
  ! You can also obtain a copy of the license at
  ! src/main/resources/legal-notices/CC-BY-NC-ND.txt.
  ! See the License for the specific language governing permissions
  ! and limitations under the License.
  !
  ! If applicable, add the following below this CCPL HEADER, with the fields
  ! enclosed by brackets "[]" replaced with your own identifying information:
  !      Portions Copyright [yyyy] [name of copyright owner]
  !
  ! CCPL HEADER END
  !
  !      Copyright 2011 ForgeRock AS
  !
-->
<project name="${project.name}" xmlns="http://maven.apache.org/DECORATION/1.0.1"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/DECORATION/1.0.1 http://maven.apache.org/xsd/decoration-1.0.1.xsd">
  <body>
    <menu ref="parent" />
    <menu ref="reports" />
  </body>
  <custom>
    <googleAnalytics>UA-23412190-2</googleAnalytics>
    <openproject>
      <href>http://opendj.org/</href>
      <src>./images/opendj-tagline-179x65.png</src>
      <alt>OpenDJ</alt>
    </openproject>
  </custom>
</project>
opendj3/opendj-ldap-sdk-examples/src/site/site_fr.xml
New file
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<project name="Maven" xmlns="http://maven.apache.org/DECORATION/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/DECORATION/1.0.0 http://maven.apache.org/xsd/decoration-1.0.0.xsd">
  <bannerLeft>
    <name>Maven</name>
    <src>http://maven.apache.org/images/apache-maven-project.png</src>
    <href>http://maven.apache.org/</href>
  </bannerLeft>
  <bannerRight>
    <src>http://maven.apache.org/images/maven-small.gif</src>
  </bannerRight>
  <body>
    <links>
      <item name="Apache" href="http://www.apache.org/" />
      <item name="Maven 1.0" href="http://maven.apache.org/"/>
      <item name="Maven 2" href="http://maven.apache.org/maven2/"/>
    </links>
    <menu name="Maven 2.0">
      <item name="Format APT" href="format.html"/>
      <item name="FAQ" href="faq.html"/>
      <item name="Exemple Xdoc" href="xdoc.html"/>
    </menu>
  </body>
</project>
opendj3/opendj-ldap-sdk-examples/src/site/xdoc/index.xml
New file
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
  ! CCPL HEADER START
  !
  ! This work is licensed under the Creative Commons
  ! Attribution-NonCommercial-NoDerivs 3.0 Unported License.
  ! To view a copy of this license, visit
  ! http://creativecommons.org/licenses/by-nc-nd/3.0/
  ! or send a letter to Creative Commons, 444 Castro Street,
  ! Suite 900, Mountain View, California, 94041, USA.
  !
  ! You can also obtain a copy of the license at
  ! src/main/resources/legal-notices/CC-BY-NC-ND.txt.
  ! See the License for the specific language governing permissions
  ! and limitations under the License.
  !
  ! If applicable, add the following below this CCPL HEADER, with the fields
  ! enclosed by brackets "[]" replaced with your own identifying information:
  !      Portions Copyright [yyyy] [name of copyright owner]
  !
  ! CCPL HEADER END
  !
  !      Copyright 2011 ForgeRock AS
  !
-->
<document xmlns="http://maven.apache.org/XDOC/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 http://maven.apache.org/xsd/xdoc-2.0.xsd">
  <properties>
    <title>About OpenDJ</title>
    <author email="opendj-dev@forgerock.org">ForgeRock AS</author>
  </properties>
  <body>
    <section name="About OpenDJ LDAP SDK Examples">
      <p>TBC</p>
    </section>
  </body>
</document>
opendj3/pom.xml
@@ -91,6 +91,7 @@
    <module>opendj-build-tools</module>
    <module>opendj-ldap-sdk</module>
    <module>opendj-ldap-toolkit</module>
    <module>opendj-ldap-sdk-examples</module>
  </modules>
  <properties>
    <docbkx-src>${basedir}/src/docbkx</docbkx-src>