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

matthew_swift
22.35.2007 89debdc4f4f38e0d973c9f4f37e1c34002deeeb4
Various improvements and refactorings of the admin framework client API, including:

* client API methods are much more specific about what sort of exceptions they can throw

* new exceptions for wrapping underlying transport related error conditions (e.g. IO problems, authorization problems)

* improved Javadoc generation for client APIs

* pull-up AbstractPropertyDefinitionVisitor into PropertyDefinitionVisitor and improve type-safety of EnumPropertyDefinition visitor method

* refactor the LDAP client implementation (remove LDAPChangeBuilder, introduce JNDI DirContext wrapper interface called LDAPConnection to make the client APIs more testable)

* move various unit test classes out of the admin server-side unit tests so that they can be re-used by client unit tests

* introduce "mock" client connections and property providers to facilitate testing of the admin client API

* implement client API unit tests
6 files deleted
19 files added
4 files renamed
17 files modified
6153 ■■■■ changed files
opendj-sdk/opends/resource/admin/clientMO.xsl 351 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/resource/admin/java-utilities.xsl 148 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/resource/admin/metaMO.xsl 84 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/admin/AbstractPropertyDefinitionVisitor.java 172 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/admin/ConfigurationClient.java 25 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/admin/LDAPProfile.java 26 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/admin/ManagedObjectAlreadyExistsException.java 27 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/admin/PropertyDefinitionVisitor.java 98 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/admin/client/AdminClientException.java 99 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/admin/client/AdminSecurityException.java 84 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/admin/client/AuthenticationException.java 90 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/admin/client/AuthenticationNotSupportedException.java 91 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/admin/client/AuthorizationException.java 91 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/admin/client/CommunicationException.java 92 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/admin/client/ConcurrentModificationException.java 95 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/admin/client/ExampleClient.java 11 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/admin/client/InitialManagedObject.java 39 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/admin/client/ManagedObject.java 457 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/admin/client/OperationRejectedException.java 94 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/JNDIDirContextAdaptor.java 239 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPChangeBuilder.java 183 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPConnection.java 140 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagedObject.java 610 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagementContext.java 109 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPNameBuilder.java 37 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/OperationsExceptionFactory.java 72 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/DurationPropertyDefinitionTest.java 2 ●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/IntegerPropertyDefinitionTest.java 2 ●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/MockLDAPProfile.java 35 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/SizePropertyDefinitionTest.java 2 ●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestChildCfg.java 10 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestChildCfgClient.java 22 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestChildCfgDefn.java 251 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestParentCfg.java 21 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestParentCfgClient.java 214 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestParentCfgDefn.java 391 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/CreateEntryMockLDAPConnection.java 137 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/DeleteSubtreeMockLDAPConnection.java 87 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/LDAPClientTest.java 625 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/MockLDAPConnection.java 358 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/MockPropertyProvider.java 111 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/ModifyEntryMockLDAPConnection.java 139 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/DNBuilderTest.java 7 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/TestChildCfgDefn.java 64 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/TestParentCfgClient.java 46 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/TestParentCfgDefn.java 65 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/resource/admin/clientMO.xsl
@@ -97,84 +97,138 @@
    </xsl:variable>
    <xsl:choose>
      <xsl:when test="adm:one-to-one">
        <xsl:call-template name="add-java-comment2">
          <xsl:with-param name="indent" select="2" />
          <xsl:with-param name="content"
            select="concat(
                       'Gets the ', $ufn,'.&#xa;',
                       '&#xa;',
                       '@return Returns the ', $ufn,'.&#xa;',
                       '@throws DefinitionDecodingException&#xa;',
                       '          If the ', $ufn, ' was found but its type could not be determined.&#xa;',
                       '@throws ManagedObjectDecodingException&#xa;',
                       '          If the ', $ufn, ' was found but one or more of its properties could not be decoded.&#xa;',
                       '@throws ManagedObjectNotFoundException&#xa;',
                       '          If the ', $ufn, ' could not be found on the server.&#xa;',
                       '@throws ConcurrentModificationException&#xa;',
                       '          If this ', $this-ufn, ' has been removed from the server by another client.&#xa;',
                       '@throws AuthorizationException&#xa;',
                       '          If the server refuses to retrieve the ', $ufn, ' because the client does not have the correct privileges.&#xa;',
                       '@throws CommunicationException&#xa;',
                       '          If the client cannot contact the server due to an underlying communication problem.')" />
        </xsl:call-template>
        <xsl:value-of
          select="concat('  /**&#xa;',
                       '   * Gets the ', $ufn,'.&#xa;',
                       '   *&#xa;',
                       '   * @return Returns the ', $ufn,'.&#xa;',
                       '   * @throws OperationsException&#xa;',
                       '   *           If the ', $ufn,' could not be read due to some&#xa;',
                       '   *           underlying communication problem.&#xa;',
                       '   */&#xa;')" />
        <xsl:value-of
          select="concat('  ', $java-class-name, 'CfgClient get',
                       $java-relation-name, '() throws OperationsException;&#xa;')" />
          select="concat('  ', $java-class-name, 'CfgClient get', $java-relation-name, '()&#xa;',
                       '      throws DefinitionDecodingException, ManagedObjectDecodingException,&#xa;',
                       '      ManagedObjectNotFoundException, ConcurrentModificationException,&#xa;',
                       '      AuthorizationException, CommunicationException;&#xa;')" />
      </xsl:when>
      <xsl:when test="adm:one-to-zero-or-one">
        <xsl:value-of
          select="concat('  /**&#xa;',
                       '   * Determines whether or not the ', $ufn,' exists.&#xa;',
                       '   *&#xa;',
                       '   * @return Returns &lt;true&gt; if the ', $ufn,' exists.&#xa;',
                       '   * @throws OperationsException&#xa;',
                       '   *           If the determination could not be made&#xa;',
                       '   *           due to some underlying communication problem.&#xa;',
                       '   */&#xa;')" />
        <xsl:call-template name="add-java-comment2">
          <xsl:with-param name="indent" select="2" />
          <xsl:with-param name="content"
            select="concat('Determines whether or not the ', $ufn,' exists.&#xa;',
                       '&#xa;',
                       '@return Returns &lt;true&gt; if the ', $ufn,' exists.&#xa;',
                       '@throws ConcurrentModificationException&#xa;',
                       '          If this ', $this-ufn, ' has been removed from the server by another client.&#xa;',
                       '@throws AuthorizationException&#xa;',
                       '          If the server refuses to make the determination because the client does not have the correct privileges.&#xa;',
                       '@throws CommunicationException&#xa;',
                       '          If the client cannot contact the server due to an underlying communication problem.')" />
        </xsl:call-template>
        <xsl:value-of
          select="concat('  boolean has',
                       $java-relation-name, '() throws OperationsException;&#xa;')" />
                       $java-relation-name, '() throws ConcurrentModificationException,&#xa;',
                       '      AuthorizationException, CommunicationException;&#xa;')" />
        <xsl:text>&#xa;</xsl:text>
        <xsl:text>&#xa;</xsl:text>
        <xsl:text>&#xa;</xsl:text>
        <xsl:call-template name="add-java-comment2">
          <xsl:with-param name="indent" select="2" />
          <xsl:with-param name="content"
            select="concat(
                       'Gets the ', $ufn,' if it is present.&#xa;',
                       '&#xa;',
                       '@return Returns the ', $ufn, ' if it is present.&#xa;',
                       '@throws DefinitionDecodingException&#xa;',
                       '          If the ', $ufn, ' was found but its type could not be determined.&#xa;',
                       '@throws ManagedObjectDecodingException&#xa;',
                       '          If the ', $ufn, ' was found but one or more of its properties could not be decoded.&#xa;',
                       '@throws ManagedObjectNotFoundException&#xa;',
                       '          If the ', $ufn, ' is not present.&#xa;',
                       '@throws ConcurrentModificationException&#xa;',
                       '          If this ', $this-ufn, ' has been removed from the server by another client.&#xa;',
                       '@throws AuthorizationException&#xa;',
                       '          If the server refuses to retrieve the ', $ufn, ' because the client does not have the correct privileges.&#xa;',
                       '@throws CommunicationException&#xa;',
                       '          If the client cannot contact the server due to an underlying communication problem.')" />
        </xsl:call-template>
        <xsl:value-of
          select="concat('  /**&#xa;',
                       '   * Gets the ', $ufn,' if it is present.&#xa;',
                       '   *&#xa;',
                       '   * @return Returns the ', $ufn,' if it is present.&#xa;',
                       '   * @throws OperationsException&#xa;',
                       '   *           If the ', $ufn,' does not exist or could not be read&#xa;',
                       '   *           due to some underlying communication problem.&#xa;',
                       '   */&#xa;')" />
        <xsl:value-of
          select="concat('  ', $java-class-name, 'CfgClient get',
                       $java-relation-name, '() throws OperationsException;&#xa;')" />
          select="concat('  ', $java-class-name, 'CfgClient get', $java-relation-name, '()&#xa;',
                       '      throws DefinitionDecodingException, ManagedObjectDecodingException,&#xa;',
                       '      ManagedObjectNotFoundException, ConcurrentModificationException,&#xa;',
                       '      AuthorizationException, CommunicationException;&#xa;')" />
        <xsl:text>&#xa;</xsl:text>
        <xsl:text>&#xa;</xsl:text>
        <xsl:text>&#xa;</xsl:text>
        <xsl:value-of
          select="concat('  /**&#xa;',
                       '   * Creates the ', $ufn,' if it does not exist yet.&#xa;',
                       '   *&#xa;',
                       '   * @param &lt;C&gt;&#xa;',
                       '   *          The type of the ', $ufn,' being added.&#xa;',
                       '   * @param d&#xa;',
                       '   *          The definition of the ', $ufn,' to be created.&#xa;',
                       '   * @param p&#xa;',
                       '   *          A property provider which can be used to initialize&#xa;',
                       '   *          the property values of the new ', $ufn,'.&#xa;',
                       '   * @return Returns the ', $ufn,' instance representing the&#xa;',
                       '   *         ', $ufn,' that was created.&#xa;',
                       '   * @throws OperationsException&#xa;',
                       '   *           If the ', $ufn,' already exists or could not be created&#xa;',
                       '   *           due to some underlying communication problem.&#xa;',
                       '   */&#xa;')" />
        <xsl:call-template name="add-java-comment2">
          <xsl:with-param name="indent" select="2" />
          <xsl:with-param name="content"
            select="concat(
                       'Creates the ', $ufn,' if it does not exist yet.&#xa;',
                       '&#xa;',
                       '@param &lt;C&gt;&#xa;',
                       '         The type of the ', $ufn,' being added.&#xa;',
                       '@param d&#xa;',
                       '         The definition of the ', $ufn,' to be created.&#xa;',
                       '@param p&#xa;',
                       '         A property provider which can be used to initialize the property values of the new ', $ufn,'.&#xa;',
                       '@return Returns the ', $ufn,' instance representing the ', $ufn,' that was created.&#xa;',
                       '@throws ManagedObjectDecodingException&#xa;',
                       '          If the ', $ufn,' could not be created because one or more of its properties are invalid.&#xa;',
                       '@throws ManagedObjectAlreadyExistsException&#xa;',
                       '          If the ', $ufn,' cannot be created because it already exists on the server.&#xa;',
                       '@throws ConcurrentModificationException&#xa;',
                       '          If this ', $ufn,' has been removed from the server by another client.&#xa;',
                       '@throws OperationRejectedException&#xa;',
                       '          If the server refuses to create the ', $ufn,' due to some server-side constraint which cannot be satisfied.&#xa;',
                       '@throws AuthorizationException&#xa;',
                       '          If the server refuses to create the ', $ufn,' because the client does not have the correct privileges.&#xa;',
                       '@throws CommunicationException&#xa;',
                       '          If the client cannot contact the server due to an underlying communication problem.&#xa;')" />
        </xsl:call-template>
        <xsl:value-of
          select="concat('  &lt;C extends ', $java-class-name,'CfgClient&gt; C create', $java-relation-name, '(&#xa;',
                           '      ManagedObjectDefinition&lt;C, ?&gt; d, PropertyProvider p) throws OperationsException;&#xa;')" />
                           '      ManagedObjectDefinition&lt;C, ?&gt; d, PropertyProvider p)&#xa;',
                           '      throws ManagedObjectDecodingException, ManagedObjectAlreadyExistsException,&#xa;',
                           '      ConcurrentModificationException, OperationRejectedException,&#xa;',
                           '      AuthorizationException, CommunicationException;&#xa;')" />
        <xsl:text>&#xa;</xsl:text>
        <xsl:text>&#xa;</xsl:text>
        <xsl:text>&#xa;</xsl:text>
        <xsl:call-template name="add-java-comment2">
          <xsl:with-param name="indent" select="2" />
          <xsl:with-param name="content"
            select="concat(
                       'Removes the ', $ufn,' if it exists.&#xa;',
                       '&#xa;',
                       '@throws ManagedObjectNotFoundException&#xa;',
                       '          If the ', $ufn, ' does not exist.&#xa;',
                       '@throws OperationRejectedException&#xa;',
                       '          If the server refuses to remove the ', $ufn, ' due to some server-side constraint which cannot be satisfied (for example, if it is referenced by another managed object).&#xa;',
                       '@throws ConcurrentModificationException&#xa;',
                       '          If this ', $this-ufn, ' has been removed from the server by another client.&#xa;',
                       '@throws AuthorizationException&#xa;',
                       '          If the server refuses to remove the ', $ufn, ' because the client does not have the correct privileges.&#xa;',
                       '@throws CommunicationException&#xa;',
                       '          If the client cannot contact the server due to an underlying communication problem.')" />
        </xsl:call-template>
        <xsl:value-of
          select="concat('  /**&#xa;',
                       '   * Removes the ', $ufn,' if it exists.&#xa;',
                       '   *&#xa;',
                       '   * @throws OperationsException&#xa;',
                       '   *           If the ', $ufn,' does not exist or could not be removed&#xa;',
                       '   *           due to some underlying communication problem.&#xa;',
                       '   */&#xa;')" />
        <xsl:value-of
          select="concat('  void remove',
                       $java-relation-name, '() throws OperationsException;&#xa;')" />
          select="concat('  void remove', $java-relation-name, '()&#xa;',
                         '      throws ManagedObjectNotFoundException, OperationRejectedException,&#xa;',
                         '      ConcurrentModificationException, AuthorizationException,&#xa;',
                         '      CommunicationException;&#xa;')" />
      </xsl:when>
      <xsl:when test="adm:one-to-many">
        <xsl:variable name="plural-name"
@@ -189,77 +243,117 @@
            <xsl:with-param name="value" select="$plural-name" />
          </xsl:call-template>
        </xsl:variable>
        <xsl:value-of
          select="concat('  /**&#xa;',
                       '   * Lists the ', $ufpn,'.&#xa;',
                       '   *&#xa;',
                       '   * @return Returns an array containing the names of the&#xa;',
                       '   *         ', $ufpn,'.&#xa;',
                       '   * @throws OperationsException&#xa;',
                       '   *           If the ', $ufpn,' could not be listed due to some&#xa;',
                       '   *           underlying communication problem.&#xa;',
                       '   */&#xa;')" />
        <xsl:call-template name="add-java-comment2">
          <xsl:with-param name="indent" select="2" />
          <xsl:with-param name="content"
            select="concat('Lists the ', $ufpn,'.&#xa;',
                       '&#xa;',
                       '@return Returns an array containing the names of the ', $ufpn,'.&#xa;',
                       '@throws ConcurrentModificationException&#xa;',
                       '          If this ', $this-ufn, ' has been removed from the server by another client.&#xa;',
                       '@throws AuthorizationException&#xa;',
                       '          If the server refuses to list the ', $ufpn, ' because the client does not have the correct privileges.&#xa;',
                       '@throws CommunicationException&#xa;',
                       '          If the client cannot contact the server due to an underlying communication problem.')" />
        </xsl:call-template>
        <xsl:value-of
          select="concat('  String[] list',
                       $java-relation-plural-name, '() throws OperationsException;&#xa;')" />
                       $java-relation-plural-name, '() throws ConcurrentModificationException,&#xa;',
                       '      AuthorizationException, CommunicationException;&#xa;')" />
        <xsl:text>&#xa;</xsl:text>
        <xsl:text>&#xa;</xsl:text>
        <xsl:text>&#xa;</xsl:text>
        <xsl:call-template name="add-java-comment2">
          <xsl:with-param name="indent" select="2" />
          <xsl:with-param name="content"
            select="concat(
                       'Gets the named ', $ufn, '.&#xa;',
                       '&#xa;',
                       '@param name&#xa;',
                       '          The name of the ', $ufn,' to retrieve.&#xa;',
                       '@return Returns the named ', $ufn, '.&#xa;',
                       '@throws DefinitionDecodingException&#xa;',
                       '          If the named ', $ufn, ' was found but its type could not be determined.&#xa;',
                       '@throws ManagedObjectDecodingException&#xa;',
                       '          If the named ', $ufn, ' was found but one or more of its properties could not be decoded.&#xa;',
                       '@throws ManagedObjectNotFoundException&#xa;',
                       '          If the named ', $ufn, ' was not found on the server.&#xa;',
                       '@throws ConcurrentModificationException&#xa;',
                       '          If this ', $this-ufn, ' has been removed from the server by another client.&#xa;',
                       '@throws AuthorizationException&#xa;',
                       '          If the server refuses to retrieve the named ', $ufn, ' because the client does not have the correct privileges.&#xa;',
                       '@throws CommunicationException&#xa;',
                       '          If the client cannot contact the server due to an underlying communication problem.')" />
        </xsl:call-template>
        <xsl:value-of
          select="concat('  /**&#xa;',
                       '   * Gets the named ', $ufn,'.&#xa;',
                       '   *&#xa;',
                       '   * @param name&#xa;',
                       '   *          The name of the ', $ufn,' to retrieve.&#xa;',
                       '   * @return Returns the named ', $ufn,'.&#xa;',
                       '   * @throws OperationsException&#xa;',
                       '   *           If the ', $ufn,' does not exist or could not be read&#xa;',
                       '   *           due to some underlying communication problem.&#xa;',
                       '   */&#xa;')" />
        <xsl:value-of
          select="concat('  ', $java-class-name, 'CfgClient get',
                       $java-relation-name, '(String name) throws OperationsException;&#xa;')" />
          select="concat('  ', $java-class-name, 'CfgClient get', $java-relation-name, '(String name)&#xa;',
                       '      throws DefinitionDecodingException, ManagedObjectDecodingException,&#xa;',
                       '      ManagedObjectNotFoundException, ConcurrentModificationException,&#xa;',
                       '      AuthorizationException, CommunicationException;&#xa;')" />
        <xsl:text>&#xa;</xsl:text>
        <xsl:text>&#xa;</xsl:text>
        <xsl:text>&#xa;</xsl:text>
        <xsl:value-of
          select="concat('  /**&#xa;',
                       '   * Creates a new ', $ufn,'.&#xa;',
                       '   *&#xa;',
                       '   * @param &lt;C&gt;&#xa;',
                       '   *          The type of the ', $ufn,' being added.&#xa;',
                       '   * @param d&#xa;',
                       '   *          The definition of the ', $ufn,' to be created.&#xa;',
                       '   * @param name&#xa;',
                       '   *          The name of the new ', $ufn,'.&#xa;',
                       '   * @param p&#xa;',
                       '   *          A property provider which can be used to initialize&#xa;',
                       '   *          the property values of the new ', $ufn,'.&#xa;',
                       '   * @return Returns a new ', $ufn,' instance representing the&#xa;',
                       '   *         ', $ufn,' that was created.&#xa;',
                       '   * @throws OperationsException&#xa;',
                       '   *           If the ', $ufn,' already exists or could not be created&#xa;',
                       '   *           due to some underlying communication problem.&#xa;',
                       '   */&#xa;')" />
        <xsl:call-template name="add-java-comment2">
          <xsl:with-param name="indent" select="2" />
          <xsl:with-param name="content"
            select="concat(
                       'Creates a new ', $ufn,'.&#xa;',
                       '&#xa;',
                       '@param &lt;C&gt;&#xa;',
                       '         The type of the ', $ufn,' being added.&#xa;',
                       '@param d&#xa;',
                       '         The definition of the ', $ufn,' to be created.&#xa;',
                       '@param name&#xa;',
                       '         The name of the new ', $ufn,'.&#xa;',
                       '@param p&#xa;',
                       '         A property provider which can be used to initialize the property values of the new ', $ufn,'.&#xa;',
                       '@return Returns a new ', $ufn,' instance representing the ', $ufn,' that was created.&#xa;',
                       '@throws ManagedObjectDecodingException&#xa;',
                       '          If the ', $ufn,' could not be created because one or more of its properties are invalid.&#xa;',
                       '@throws ManagedObjectAlreadyExistsException&#xa;',
                       '          If the ', $ufn,' cannot be created because it already exists on the server.&#xa;',
                       '@throws ConcurrentModificationException&#xa;',
                       '          If this ', $ufn,' has been removed from the server by another client.&#xa;',
                       '@throws OperationRejectedException&#xa;',
                       '          If the server refuses to create the ', $ufn,' due to some server-side constraint which cannot be satisfied.&#xa;',
                       '@throws AuthorizationException&#xa;',
                       '          If the server refuses to create the ', $ufn,' because the client does not have the correct privileges.&#xa;',
                       '@throws CommunicationException&#xa;',
                       '          If the client cannot contact the server due to an underlying communication problem.&#xa;')" />
        </xsl:call-template>
        <xsl:value-of
          select="concat('  &lt;C extends ', $java-class-name,'CfgClient&gt; C create', $java-relation-name, '(&#xa;',
                           '      ManagedObjectDefinition&lt;C, ?&gt; d, String name, PropertyProvider p) throws OperationsException;&#xa;')" />
                           '      ManagedObjectDefinition&lt;C, ?&gt; d, String name, PropertyProvider p)&#xa;',
                           '      throws ManagedObjectDecodingException, ManagedObjectAlreadyExistsException,&#xa;',
                           '      ConcurrentModificationException, OperationRejectedException,&#xa;',
                           '      AuthorizationException, CommunicationException;&#xa;')" />
        <xsl:text>&#xa;</xsl:text>
        <xsl:text>&#xa;</xsl:text>
        <xsl:text>&#xa;</xsl:text>
        <xsl:call-template name="add-java-comment2">
          <xsl:with-param name="indent" select="2" />
          <xsl:with-param name="content"
            select="concat(
                       'Removes the named ', $ufn,'.&#xa;',
                       '&#xa;',
                       '@param name&#xa;',
                       '         The name of the ', $ufn,' to remove.&#xa;',
                       '@throws ManagedObjectNotFoundException&#xa;',
                       '          If the ', $ufn, ' does not exist.&#xa;',
                       '@throws OperationRejectedException&#xa;',
                       '          If the server refuses to remove the ', $ufn, ' due to some server-side constraint which cannot be satisfied (for example, if it is referenced by another managed object).&#xa;',
                       '@throws ConcurrentModificationException&#xa;',
                       '          If this ', $this-ufn, ' has been removed from the server by another client.&#xa;',
                       '@throws AuthorizationException&#xa;',
                       '          If the server refuses to remove the ', $ufn, ' because the client does not have the correct privileges.&#xa;',
                       '@throws CommunicationException&#xa;',
                       '          If the client cannot contact the server due to an underlying communication problem.')" />
        </xsl:call-template>
        <xsl:value-of
          select="concat('  /**&#xa;',
                       '   * Removes the named ', $ufn,'.&#xa;',
                       '   *&#xa;',
                       '   * @param name&#xa;',
                       '   *          The name of the ', $ufn,' to remove.&#xa;',
                       '   * @throws OperationsException&#xa;',
                       '   *           If the ', $ufn,' does not exist or could not be removed&#xa;',
                       '   *           due to some underlying communication problem.&#xa;',
                       '   */&#xa;')" />
        <xsl:value-of
          select="concat('  void remove',
                       $java-relation-name, '(String name) throws OperationsException;&#xa;')" />
          select="concat('  void remove', $java-relation-name, '(String name)&#xa;',
                         '      throws ManagedObjectNotFoundException, OperationRejectedException,&#xa;',
                         '      ConcurrentModificationException, AuthorizationException,&#xa;',
                         '      CommunicationException;&#xa;')" />
      </xsl:when>
      <xsl:otherwise>
        <xsl:message terminate="yes">
@@ -294,11 +388,34 @@
          </import>
        </xsl:if>
        <xsl:if test="$this-local-relations">
          <import>org.opends.server.admin.OperationsException</import>
          <import>
            org.opends.server.admin.DefinitionDecodingException
          </import>
          <import>
            org.opends.server.admin.ManagedObjectNotFoundException
          </import>
          <import>
            org.opends.server.admin.client.ManagedObjectDecodingException
          </import>
          <import>
            org.opends.server.admin.client.ConcurrentModificationException
          </import>
          <import>
            org.opends.server.admin.client.AuthorizationException
          </import>
          <import>
            org.opends.server.admin.client.CommunicationException
          </import>
        </xsl:if>
        <xsl:if
          test="$this-local-relations/adm:one-to-zero-or-one|$this-local-relations/adm:one-to-many">
          <import>org.opends.server.admin.PropertyProvider</import>
          <import>
            org.opends.server.admin.ManagedObjectAlreadyExistsException
          </import>
          <import>
            org.opends.server.admin.client.OperationRejectedException
          </import>
        </xsl:if>
        <xsl:choose>
          <xsl:when test="$this/@extends">
opendj-sdk/opends/resource/admin/java-utilities.xsl
@@ -143,6 +143,145 @@
    </xsl:call-template>
  </xsl:template>
  <!--
    Add a Java comment at the specified indentation.
    This template handles embedded newline characters
    and will also indent individual lines according to
    the number of leading spaces they contain.
    @param indent
    The indentation column for the comment.
    @param content
    The content to be output in the comment.
  -->
  <xsl:template name="add-java-comment2">
    <xsl:param name="indent" select="/.." />
    <xsl:param name="content" select="/.." />
    <!--  Compute the indentation string. -->
    <xsl:variable name="indent-text">
      <xsl:call-template name="add-indent">
        <xsl:with-param name="indent" select="$indent + 1" />
      </xsl:call-template>
      <xsl:value-of select="'*'" />
    </xsl:variable>
    <!--  Output the comment header. -->
    <xsl:call-template name="add-indent">
      <xsl:with-param name="indent" select="$indent" />
    </xsl:call-template>
    <xsl:value-of select="'/**&#xa;'" />
    <!--  Output the comment contents. -->
    <xsl:call-template name="add-java-comment-line">
      <xsl:with-param name="indent-text" select="$indent-text" />
      <xsl:with-param name="content" select="$content" />
    </xsl:call-template>
    <!--  Output the header trailer. -->
    <xsl:value-of select="concat($indent-text, '/&#xa;')" />
  </xsl:template>
  <!-- Creates a padding string of the required length. -->
  <xsl:template name="add-indent">
    <xsl:param name="indent" select="/.." />
    <xsl:if test="$indent > 0">
      <xsl:value-of select="' '" />
      <xsl:call-template name="add-indent">
        <xsl:with-param name="indent" select="$indent - 1" />
      </xsl:call-template>
    </xsl:if>
  </xsl:template>
  <xsl:template name="add-java-comment-line">
    <xsl:param name="indent-text" select="/.." />
    <xsl:param name="content" select="/.." />
    <!--  Get the next line. -->
    <xsl:variable name="head"
      select="substring-before($content, '&#xa;')" />
    <xsl:variable name="tail"
      select="substring-after($content, '&#xa;')" />
    <!--
      Case #1 - content is empty
      Case #2 - no newline
      Case #3 - contains a new line
      Case #3.1 - begins with newline
      Case #3.2 - ends with newline
    -->
    <xsl:choose>
      <xsl:when test="string-length($content) = 0">
        <!-- Do nothing. -->
      </xsl:when>
      <xsl:when test="not(contains($content, '&#xa;'))">
        <!-- Single line of text. -->
        <xsl:call-template name="java-format-line">
          <xsl:with-param name="indent-text" select="$indent-text" />
          <xsl:with-param name="line" select="$content" />
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <!-- Output the first line and repeat for remaining lines. -->
        <xsl:call-template name="java-format-line">
          <xsl:with-param name="indent-text" select="$indent-text" />
          <xsl:with-param name="line" select="$head" />
        </xsl:call-template>
        <xsl:call-template name="add-java-comment-line">
          <xsl:with-param name="indent-text" select="$indent-text" />
          <xsl:with-param name="content" select="$tail" />
        </xsl:call-template>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  <!-- Formats a line of comment text. -->
  <xsl:template name="java-format-line">
    <xsl:param name="indent-text" select="/.." />
    <xsl:param name="line" select="/.." />
    <!--  First count the number of leading spaces to determine the indent. -->
    <xsl:variable name="leading-spaces">
      <xsl:call-template name="java-format-line-help">
        <xsl:with-param name="line" select="$line" />
      </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="content"
      select="substring($line, $leading-spaces + 1)" />
    <xsl:variable name="padding1">
      <xsl:value-of select="$indent-text" />
      <xsl:call-template name="add-indent">
        <xsl:with-param name="indent" select="$leading-spaces" />
      </xsl:call-template>
    </xsl:variable>
    <!-- We need to use indent2 for certain javadoc keywords. -->
    <xsl:variable name="padding2">
      <xsl:choose>
        <xsl:when test="starts-with($content, '@return')">
          <xsl:value-of select="concat($padding1, '        ')" />
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="$padding1" />
        </xsl:otherwise>
      </xsl:choose>
    </xsl:variable>
    <!-- Now output the line, wrapping as necessary. -->
    <xsl:call-template name="format-text">
      <xsl:with-param name="indent-text" select="$padding1" />
      <xsl:with-param name="indent-text2" select="$padding2" />
      <xsl:with-param name="wrap-column" select="'70'" />
      <xsl:with-param name="content" select="$content" />
    </xsl:call-template>
  </xsl:template>
  <!--  Determines the number of leading spaces in the provided string. -->
  <xsl:template name="java-format-line-help">
    <xsl:param name="line" select="/.." />
    <xsl:param name="count" select="0" />
    <xsl:choose>
      <xsl:when test="starts-with($line, ' ')">
        <xsl:call-template name="java-format-line-help">
          <xsl:with-param name="line"
            select="substring-after($line, ' ')" />
          <xsl:with-param name="count" select="$count + 1" />
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$count" />
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  <!--
    Utility template for removing duplicate values from a node-set.
    
    This template is based on the version published on the XSLT site.
@@ -168,13 +307,16 @@
          <xsl:when test="$distinct[. = $value]">
            <xsl:call-template name="_set-distinct">
              <xsl:with-param name="distinct" select="$distinct" />
              <xsl:with-param name="nodes" select="$nodes[position() > 1]" />
              <xsl:with-param name="nodes"
                select="$nodes[position() > 1]" />
            </xsl:call-template>
          </xsl:when>
          <xsl:otherwise>
            <xsl:call-template name="_set-distinct">
              <xsl:with-param name="distinct" select="$distinct | $nodes[1]" />
              <xsl:with-param name="nodes" select="$nodes[position() > 1]" />
              <xsl:with-param name="distinct"
                select="$distinct | $nodes[1]" />
              <xsl:with-param name="nodes"
                select="$nodes[position() > 1]" />
            </xsl:call-template>
          </xsl:otherwise>
        </xsl:choose>
opendj-sdk/opends/resource/admin/metaMO.xsl
@@ -387,7 +387,9 @@
      select="concat('    /**&#xa;',
                     '     * {@inheritDoc}&#xa;',
                     '     */&#xa;',
                     '    public void commit() throws OperationsException {&#xa;',
                     '    public void commit() throws ConcurrentModificationException,&#xa;',
                     '        OperationRejectedException, AuthorizationException,&#xa;',
                     '        CommunicationException {&#xa;',
                     '      impl.commit();&#xa;',
                     '    }&#xa;')" />
    <xsl:text>&#xa;</xsl:text>
@@ -1080,8 +1082,10 @@
          select="concat('    /**&#xa;',
                         '     * {@inheritDoc}&#xa;',
                         '     */&#xa;',
                         '    public ', $java-class-name, 'CfgClient get',
                         $java-relation-name, '() throws OperationsException {&#xa;',
                         '    public ', $java-class-name, 'CfgClient get', $java-relation-name, '()&#xa;',
                         '        throws DefinitionDecodingException, ManagedObjectDecodingException,&#xa;',
                         '        ManagedObjectNotFoundException, ConcurrentModificationException,&#xa;',
                         '        AuthorizationException, CommunicationException {&#xa;',
                         '      return impl.getChild(INSTANCE.get', $java-relation-name,'RelationDefinition()).getConfiguration();&#xa;',
                         '    }&#xa;')" />
      </xsl:when>
@@ -1090,8 +1094,8 @@
          select="concat('    /**&#xa;',
                         '     * {@inheritDoc}&#xa;',
                         '     */&#xa;',
                         '    public boolean has',
                         $java-relation-name, '() throws OperationsException {&#xa;',
                         '    public boolean has', $java-relation-name, '() throws ConcurrentModificationException,&#xa;',
                         '        AuthorizationException, CommunicationException {&#xa;',
                         '      return impl.hasChild(INSTANCE.get', $java-relation-name,'RelationDefinition());&#xa;',
                         '    }&#xa;')" />
        <xsl:text>&#xa;</xsl:text>
@@ -1101,8 +1105,10 @@
          select="concat('    /**&#xa;',
                         '     * {@inheritDoc}&#xa;',
                         '     */&#xa;',
                         '    public ', $java-class-name, 'CfgClient get',
                         $java-relation-name, '() throws OperationsException {&#xa;',
                         '    public ', $java-class-name, 'CfgClient get', $java-relation-name, '()&#xa;',
                         '        throws DefinitionDecodingException, ManagedObjectDecodingException,&#xa;',
                         '        ManagedObjectNotFoundException, ConcurrentModificationException,&#xa;',
                         '        AuthorizationException, CommunicationException {&#xa;',
                         '      return impl.getChild(INSTANCE.get', $java-relation-name,'RelationDefinition()).getConfiguration();&#xa;',
                         '    }&#xa;')" />
        <xsl:text>&#xa;</xsl:text>
@@ -1112,8 +1118,11 @@
          select="concat('    /**&#xa;',
                         '     * {@inheritDoc}&#xa;',
                         '     */&#xa;',
                         '    public &lt;M extends ', $java-class-name, 'CfgClient&gt; M create',
                         $java-relation-name, '(ManagedObjectDefinition&lt;M, ?&gt; d, PropertyProvider p) throws OperationsException {&#xa;',
                         '    public &lt;M extends ', $java-class-name, 'CfgClient&gt; M create', $java-relation-name, '(&#xa;',
                         '        ManagedObjectDefinition&lt;M, ?&gt; d, PropertyProvider p)&#xa;',
                         '        throws ManagedObjectDecodingException, ManagedObjectAlreadyExistsException,&#xa;',
                         '        ConcurrentModificationException, OperationRejectedException,&#xa;',
                         '        AuthorizationException, CommunicationException {&#xa;',
                         '      return impl.createChild(INSTANCE.get', $java-relation-name,'RelationDefinition(), d, p).getConfiguration();&#xa;',
                         '    }&#xa;')" />
        <xsl:text>&#xa;</xsl:text>
@@ -1123,8 +1132,9 @@
          select="concat('    /**&#xa;',
                         '     * {@inheritDoc}&#xa;',
                         '     */&#xa;',
                         '    public void remove',
                         $java-relation-name, '() throws OperationsException {&#xa;',
                         '    public void remove', $java-relation-name, '()&#xa;',
                         '        throws ManagedObjectNotFoundException, ConcurrentModificationException,&#xa;',
                         '        OperationRejectedException, AuthorizationException, CommunicationException {&#xa;',
                         '      impl.removeChild(INSTANCE.get', $java-relation-name,'RelationDefinition());&#xa;',
                         '    }&#xa;')" />
      </xsl:when>
@@ -1140,8 +1150,8 @@
          select="concat('    /**&#xa;',
                         '     * {@inheritDoc}&#xa;',
                         '     */&#xa;',
                         '    public String[] list',
                         $java-relation-plural-name, '() throws OperationsException {&#xa;',
                         '    public String[] list', $java-relation-plural-name, '() throws ConcurrentModificationException,&#xa;',
                         '        AuthorizationException, CommunicationException {&#xa;',
                         '      return impl.listChildren(INSTANCE.get', $java-relation-plural-name,'RelationDefinition());&#xa;',
                         '    }&#xa;')" />
        <xsl:text>&#xa;</xsl:text>
@@ -1151,8 +1161,10 @@
          select="concat('    /**&#xa;',
                         '     * {@inheritDoc}&#xa;',
                         '     */&#xa;',
                         '    public ', $java-class-name, 'CfgClient get',
                         $java-relation-name, '(String name) throws OperationsException {&#xa;',
                         '    public ', $java-class-name, 'CfgClient get', $java-relation-name, '(String name)&#xa;',
                         '        throws DefinitionDecodingException, ManagedObjectDecodingException,&#xa;',
                         '        ManagedObjectNotFoundException, ConcurrentModificationException,&#xa;',
                         '        AuthorizationException, CommunicationException {&#xa;',
                         '      return impl.getChild(INSTANCE.get', $java-relation-plural-name,'RelationDefinition(), name).getConfiguration();&#xa;',
                         '    }&#xa;')" />
        <xsl:text>&#xa;</xsl:text>
@@ -1162,8 +1174,11 @@
          select="concat('    /**&#xa;',
                         '     * {@inheritDoc}&#xa;',
                         '     */&#xa;',
                         '    public &lt;M extends ', $java-class-name, 'CfgClient&gt; M create',
                         $java-relation-name, '(ManagedObjectDefinition&lt;M, ?&gt; d, String name, PropertyProvider p) throws OperationsException {&#xa;',
                         '    public &lt;M extends ', $java-class-name, 'CfgClient&gt; M create', $java-relation-name, '(&#xa;',
                         '        ManagedObjectDefinition&lt;M, ?&gt; d, String name, PropertyProvider p)&#xa;',
                         '        throws ManagedObjectDecodingException, ManagedObjectAlreadyExistsException,&#xa;',
                         '        ConcurrentModificationException, OperationRejectedException,&#xa;',
                         '        AuthorizationException, CommunicationException {&#xa;',
                         '      return impl.createChild(INSTANCE.get', $java-relation-plural-name,'RelationDefinition(), d, name, p).getConfiguration();&#xa;',
                         '    }&#xa;')" />
        <xsl:text>&#xa;</xsl:text>
@@ -1173,8 +1188,9 @@
          select="concat('    /**&#xa;',
                         '     * {@inheritDoc}&#xa;',
                         '     */&#xa;',
                         '    public void remove',
                         $java-relation-name, '(String name) throws OperationsException {&#xa;',
                         '    public void remove', $java-relation-name, '(String name)&#xa;',
                         '        throws ManagedObjectNotFoundException, ConcurrentModificationException,&#xa;',
                         '        OperationRejectedException, AuthorizationException, CommunicationException {&#xa;',
                         '      impl.removeChild(INSTANCE.get', $java-relation-plural-name,'RelationDefinition(), name);&#xa;',
                         '    }&#xa;')" />
      </xsl:when>
@@ -1638,7 +1654,18 @@
              org.opends.server.admin.ManagedObjectDefinition
            </import>
            <import>org.opends.server.admin.PropertyProvider</import>
            <import>org.opends.server.admin.OperationsException</import>
            <import>
              org.opends.server.admin.client.AuthorizationException
            </import>
            <import>
              org.opends.server.admin.client.CommunicationException
            </import>
            <import>
              org.opends.server.admin.client.ConcurrentModificationException
            </import>
            <import>
              org.opends.server.admin.client.OperationRejectedException
            </import>
            <import>
              org.opends.server.admin.client.ManagedObject
            </import>
@@ -1653,8 +1680,22 @@
                name="generate-change-listener-import-statements" />
            </xsl:if>
            <import>org.opends.server.types.DN</import>
            <xsl:if test="$this-all-relations">
              <import>
                org.opends.server.admin.DefinitionDecodingException
              </import>
              <import>
                org.opends.server.admin.ManagedObjectNotFoundException
              </import>
              <import>
                org.opends.server.admin.client.ManagedObjectDecodingException
              </import>
            </xsl:if>
            <xsl:if test="$this-all-relations/adm:one-to-many">
              <import>
                org.opends.server.admin.ManagedObjectAlreadyExistsException
              </import>
              <import>
                org.opends.server.admin.server.ConfigurationAddListener
              </import>
              <import>
@@ -1664,6 +1705,9 @@
            </xsl:if>
            <xsl:if test="$this-all-relations/adm:one-to-zero-or-one">
              <import>
                org.opends.server.admin.ManagedObjectAlreadyExistsException
              </import>
              <import>
                org.opends.server.admin.server.ConfigurationAddListener
              </import>
              <import>
opendj-sdk/opends/src/server/org/opends/server/admin/AbstractPropertyDefinitionVisitor.java
File was deleted
opendj-sdk/opends/src/server/org/opends/server/admin/ConfigurationClient.java
@@ -27,6 +27,11 @@
package org.opends.server.admin;
import org.opends.server.admin.client.AuthorizationException;
import org.opends.server.admin.client.CommunicationException;
import org.opends.server.admin.client.ConcurrentModificationException;
import org.opends.server.admin.client.OperationRejectedException;
/**
@@ -59,11 +64,21 @@
  /**
   * Commit any changes made to this configuration client.
   *
   * @throws OperationsException
   *           If the changes to this configuration client could not
   *           be committed due to some underlying communication
   *           problem.
   * @throws ConcurrentModificationException
   *           If this configuration has been removed from the server
   *           by another client.
   * @throws OperationRejectedException
   *           If the server refuses to apply the changes due to some
   *           server-side constraint which cannot be satisfied.
   * @throws AuthorizationException
   *           If the server refuses to apply the changes because the
   *           client does not have the correct privileges.
   * @throws CommunicationException
   *           If the client cannot contact the server due to an
   *           underlying communication problem.
   */
  void commit() throws OperationsException;
  void commit() throws ConcurrentModificationException,
      OperationRejectedException, AuthorizationException,
      CommunicationException;
}
opendj-sdk/opends/src/server/org/opends/server/admin/LDAPProfile.java
@@ -123,19 +123,6 @@
    /**
     * {@inheritDoc}
     */
    public String getFilter(AbstractManagedObjectDefinition<?, ?> d) {
      StringBuilder builder = new StringBuilder();
      builder.append("(ObjectClass=");
      builder.append(getObjectClass(d));
      builder.append(')');
      return builder.toString();
    }
    /**
     * {@inheritDoc}
     */
    public String getObjectClass(
        AbstractManagedObjectDefinition<?, ?> d) {
      return resource.getString(d, "objectclass");
@@ -225,19 +212,6 @@
  /**
   * Get an LDAP filter string which can be used to search for entries
   * matching the specified definition.
   *
   * @param d
   *          The managed object definition.
   * @return Returns the LDAP filter.
   */
  public abstract String getFilter(
      AbstractManagedObjectDefinition<?, ?> d);
  /**
   * Get the principle object class associated with the specified
   * definition.
   *
opendj-sdk/opends/src/server/org/opends/server/admin/ManagedObjectAlreadyExistsException.java
@@ -30,8 +30,8 @@
/**
 * A managed object could not be created because there is an existing managed
 * object with the same name.
 * A managed object could not be created because there is an existing
 * managed object with the same name.
 */
public final class ManagedObjectAlreadyExistsException extends
    OperationsException {
@@ -45,31 +45,12 @@
  private static final String MSG = "A managed object could not be created"
      + " because there is an existing managed object with the same name";
  // The name of the managed object that could not be created.
  private final String name;
  /**
   * Create a managed object already exists exception with the duplicate name.
   *
   * @param name
   *          The name of the managed object that could not be created.
   * Create a managed object already exists exception.
   */
  public ManagedObjectAlreadyExistsException(String name) {
  public ManagedObjectAlreadyExistsException() {
    super(MSG);
    this.name = name;
  }
  /**
   * Get the name of the managed object that could not be created.
   *
   * @return Returns the name of the managed object that could not be created.
   */
  public String getName() {
    return name;
  }
}
opendj-sdk/opends/src/server/org/opends/server/admin/PropertyDefinitionVisitor.java
@@ -37,6 +37,12 @@
 * passed to a property definition's accept method, the corresponding
 * visit method most applicable to that property definition is
 * invoked.
 * <p>
 * Each <code>visitXXX</code> method is provided with a default
 * implementation which calls
 * {@link #visitUnknown(PropertyDefinition, Object)}. Sub-classes can
 * override any or all of the methods to provide their own
 * type-specific behavior.
 *
 * @param <R>
 *          The return type of this visitor's methods. Use
@@ -47,7 +53,16 @@
 *          methods. Use {@link java.lang.Void} for visitors that do
 *          not need an additional parameter.
 */
public interface PropertyDefinitionVisitor<R, P> {
public abstract class PropertyDefinitionVisitor<R, P> {
  /**
   * Default constructor.
   */
  protected PropertyDefinitionVisitor() {
    // No implementation required.
  }
  /**
   * Visit an attribute type property definition.
@@ -58,7 +73,9 @@
   *          A visitor specified parameter.
   * @return Returns a visitor specified result.
   */
  R visitAttributeType(AttributeTypePropertyDefinition d, P p);
  public R visitAttributeType(AttributeTypePropertyDefinition d, P p) {
    return visitUnknown(d, p);
  }
@@ -71,7 +88,9 @@
   *          A visitor specified parameter.
   * @return Returns a visitor specified result.
   */
  R visitBoolean(BooleanPropertyDefinition d, P p);
  public R visitBoolean(BooleanPropertyDefinition d, P p) {
    return visitUnknown(d, p);
  }
@@ -84,7 +103,9 @@
   *          A visitor specified parameter.
   * @return Returns a visitor specified result.
   */
  R visitClass(ClassPropertyDefinition d, P p);
  public R visitClass(ClassPropertyDefinition d, P p) {
    return visitUnknown(d, p);
  }
@@ -97,7 +118,9 @@
   *          A visitor specified parameter.
   * @return Returns a visitor specified result.
   */
  R visitDN(DNPropertyDefinition d, P p);
  public R visitDN(DNPropertyDefinition d, P p) {
    return visitUnknown(d, p);
  }
@@ -110,7 +133,27 @@
   *          A visitor specified parameter.
   * @return Returns a visitor specified result.
   */
  R visitDuration(DurationPropertyDefinition d, P p);
  public R visitDuration(DurationPropertyDefinition d, P p) {
    return visitUnknown(d, p);
  }
  /**
   * Visit an enumeration property definition.
   *
   * @param <E>
   *          The enumeration that should be used for values of the
   *          property definition.
   * @param d
   *          The enumeration property definition to visit.
   * @param p
   *          A visitor specified parameter.
   * @return Returns a visitor specified result.
   */
  public <E extends Enum<E>> R visitEnum(EnumPropertyDefinition<E> d, P p) {
    return visitUnknown(d, p);
  }
@@ -123,7 +166,9 @@
   *          A visitor specified parameter.
   * @return Returns a visitor specified result.
   */
  R visitInteger(IntegerPropertyDefinition d, P p);
  public R visitInteger(IntegerPropertyDefinition d, P p) {
    return visitUnknown(d, p);
  }
@@ -136,7 +181,9 @@
   *          A visitor specified parameter.
   * @return Returns a visitor specified result.
   */
  R visitIPAddress(IPAddressPropertyDefinition d, P p);
  public R visitIPAddress(IPAddressPropertyDefinition d, P p) {
    return visitUnknown(d, p);
  }
@@ -149,7 +196,9 @@
   *          A visitor specified parameter.
   * @return Returns a visitor specified result.
   */
  R visitIPAddressMask(IPAddressMaskPropertyDefinition d, P p);
  public R visitIPAddressMask(IPAddressMaskPropertyDefinition d, P p) {
    return visitUnknown(d, p);
  }
@@ -162,7 +211,9 @@
   *          A visitor specified parameter.
   * @return Returns a visitor specified result.
   */
  R visitSize(SizePropertyDefinition d, P p);
  public R visitSize(SizePropertyDefinition d, P p) {
    return visitUnknown(d, p);
  }
@@ -175,7 +226,9 @@
   *          A visitor specified parameter.
   * @return Returns a visitor specified result.
   */
  R visitString(StringPropertyDefinition d, P p);
  public R visitString(StringPropertyDefinition d, P p) {
    return visitUnknown(d, p);
  }
@@ -183,6 +236,10 @@
   * Visit an unknown type of property definition. Implementations of
   * this method can provide default behavior for unknown property
   * definition types.
   * <p>
   * The default implementation of this method throws an
   * {@link UnknownPropertyDefinitionException}. Sub-classes can
   * override this method with their own default behavior.
   *
   * @param d
   *          The property definition to visit.
@@ -193,20 +250,9 @@
   *           Visitor implementations may optionally throw this
   *           exception.
   */
  R visitUnknown(PropertyDefinition d, P p)
      throws UnknownPropertyDefinitionException;
  /**
   * Visit an enumeration property definition.
   *
   * @param d
   *          The enumeration property definition to visit.
   * @param p
   *          A visitor specified parameter.
   * @return Returns a visitor specified result.
   */
  R visitEnum(EnumPropertyDefinition<?> d, P p);
  public R visitUnknown(PropertyDefinition d, P p)
      throws UnknownPropertyDefinitionException {
    throw new UnknownPropertyDefinitionException(d, p);
  }
}
opendj-sdk/opends/src/server/org/opends/server/admin/client/AdminClientException.java
New file
@@ -0,0 +1,99 @@
/*
 * 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/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * 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/opends/resource/legal-notices/OpenDS.LICENSE.  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
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.server.admin.client;
import org.opends.server.admin.AdminException;
/**
 * Administration client exceptions represent non-operational problems
 * which occur whilst interacting with the administration framework.
 * They provide clients with a transport independent interface for
 * handling transport related exceptions.
 * <p>
 * Client exceptions represent communications problems, security
 * problems, and service related problems.
 */
public class AdminClientException extends AdminException {
  /**
   * Serialization ID.
   */
  private static final long serialVersionUID = 4044747533980824456L;
  /**
   * Create an administration client exception.
   */
  public AdminClientException() {
    // No implementation required.
  }
  /**
   * Create an administration client exception with a cause.
   *
   * @param cause
   *          The cause.
   */
  public AdminClientException(Throwable cause) {
    super(cause);
  }
  /**
   * Create an administration client exception with a message and
   * cause.
   *
   * @param message
   *          The message.
   * @param cause
   *          The cause.
   */
  public AdminClientException(String message, Throwable cause) {
    super(message, cause);
  }
  /**
   * Create an administration client exception with a message.
   *
   * @param message
   *          The message.
   */
  public AdminClientException(String message) {
    super(message);
  }
}
opendj-sdk/opends/src/server/org/opends/server/admin/client/AdminSecurityException.java
New file
@@ -0,0 +1,84 @@
/*
 * 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/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * 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/opends/resource/legal-notices/OpenDS.LICENSE.  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
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.server.admin.client;
/**
 * This exception is thrown when a security related problem occurs
 * whilst interacting with the Directory Server. These fall broadly
 * into two categories: authentication problems and authorization
 * problems.
 */
public abstract class AdminSecurityException extends AdminClientException {
  /**
   * Create a security exception.
   */
  protected AdminSecurityException() {
    // No implementation required.
  }
  /**
   * Create a security exception with a cause.
   *
   * @param cause
   *          The cause.
   */
  protected AdminSecurityException(Throwable cause) {
    super(cause);
  }
  /**
   * Create a security exception with a message and cause.
   *
   * @param message
   *          The message.
   * @param cause
   *          The cause.
   */
  protected AdminSecurityException(String message, Throwable cause) {
    super(message, cause);
  }
  /**
   * Create a security exception with a message.
   *
   * @param message
   *          The message.
   */
  protected AdminSecurityException(String message) {
    super(message);
  }
}
opendj-sdk/opends/src/server/org/opends/server/admin/client/AuthenticationException.java
New file
@@ -0,0 +1,90 @@
/*
 * 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/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * 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/opends/resource/legal-notices/OpenDS.LICENSE.  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
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.server.admin.client;
/**
 * This exception is thrown when an authentication error occurs while
 * connecting to the Directory Server. An authentication error can
 * happen, for example, when the client credentials are invalid.
 */
public class AuthenticationException extends AdminSecurityException {
  /**
   * Serialization ID.
   */
  private static final long serialVersionUID = 3544797197747686958L;
  /**
   * Create an authentication exception.
   */
  public AuthenticationException() {
    // No implementation required.
  }
  /**
   * Create an authentication exception with a cause.
   *
   * @param cause
   *          The cause.
   */
  public AuthenticationException(Throwable cause) {
    super(cause);
  }
  /**
   * Create an authentication exception with a message and cause.
   *
   * @param message
   *          The message.
   * @param cause
   *          The cause.
   */
  public AuthenticationException(String message, Throwable cause) {
    super(message, cause);
  }
  /**
   * Create an authentication exception with a message.
   *
   * @param message
   *          The message.
   */
  public AuthenticationException(String message) {
    super(message);
  }
}
opendj-sdk/opends/src/server/org/opends/server/admin/client/AuthenticationNotSupportedException.java
New file
@@ -0,0 +1,91 @@
/*
 * 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/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * 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/opends/resource/legal-notices/OpenDS.LICENSE.  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
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.server.admin.client;
/**
 * This exception is thrown when the particular flavor of
 * authentication requested is not supported by the Directory Server.
 */
public class AuthenticationNotSupportedException
    extends AdminSecurityException {
  /**
   * Serialization ID.
   */
  private static final long serialVersionUID = 7387834052676291793L;
  /**
   * Create an authentication not supported exception.
   */
  public AuthenticationNotSupportedException() {
    // No implementation required.
  }
  /**
   * Create an authentication not supported exception with a cause.
   *
   * @param cause
   *          The cause.
   */
  public AuthenticationNotSupportedException(Throwable cause) {
    super(cause);
  }
  /**
   * Create an authentication not supported exception with a message
   * and cause.
   *
   * @param message
   *          The message.
   * @param cause
   *          The cause.
   */
  public AuthenticationNotSupportedException(String message, Throwable cause) {
    super(message, cause);
  }
  /**
   * Create an authentication not supported exception with a message.
   *
   * @param message
   *          The message.
   */
  public AuthenticationNotSupportedException(String message) {
    super(message);
  }
}
opendj-sdk/opends/src/server/org/opends/server/admin/client/AuthorizationException.java
New file
@@ -0,0 +1,91 @@
/*
 * 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/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * 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/opends/resource/legal-notices/OpenDS.LICENSE.  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
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.server.admin.client;
/**
 * This exception is thrown when an authorization error occurs while
 * interacting with the Directory Server. Authorization errors can
 * occur when a client attempts to perform an administrative operation
 * which they are not permitted to perform.
 */
public class AuthorizationException extends AdminSecurityException {
  /**
   * Serialization ID.
   */
  private static final long serialVersionUID = 8414248362572933814L;
  /**
   * Create an authorization exception.
   */
  public AuthorizationException() {
    // No implementation required.
  }
  /**
   * Create an authorization exception with a cause.
   *
   * @param cause
   *          The cause.
   */
  public AuthorizationException(Throwable cause) {
    super(cause);
  }
  /**
   * Create an authorization exception with a message and cause.
   *
   * @param message
   *          The message.
   * @param cause
   *          The cause.
   */
  public AuthorizationException(String message, Throwable cause) {
    super(message, cause);
  }
  /**
   * Create an authorization exception with a message.
   *
   * @param message
   *          The message.
   */
  public AuthorizationException(String message) {
    super(message);
  }
}
opendj-sdk/opends/src/server/org/opends/server/admin/client/CommunicationException.java
New file
@@ -0,0 +1,92 @@
/*
 * 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/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * 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/opends/resource/legal-notices/OpenDS.LICENSE.  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
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.server.admin.client;
/**
 * This exception is thrown when a communications related problem
 * occurs whilst interacting with the Directory Server. This may be
 * caused by problems such as network partitioning, the unavailability
 * of the Directory Server, or other failures on the client or server
 * side.
 */
public class CommunicationException extends AdminClientException {
  /**
   * Serialization ID.
   */
  private static final long serialVersionUID = 9093195928501281027L;
  /**
   * Create a communication exception.
   */
  public CommunicationException() {
    // No implementation required.
  }
  /**
   * Create a communication exception with a cause.
   *
   * @param cause
   *          The cause.
   */
  public CommunicationException(Throwable cause) {
    super(cause);
  }
  /**
   * Create a communication exception with a message and cause.
   *
   * @param message
   *          The message.
   * @param cause
   *          The cause.
   */
  public CommunicationException(String message, Throwable cause) {
    super(message, cause);
  }
  /**
   * Create a communication exception with a message.
   *
   * @param message
   *          The message.
   */
  public CommunicationException(String message) {
    super(message);
  }
}
opendj-sdk/opends/src/server/org/opends/server/admin/client/ConcurrentModificationException.java
New file
@@ -0,0 +1,95 @@
/*
 * 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/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * 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/opends/resource/legal-notices/OpenDS.LICENSE.  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
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.server.admin.client;
import org.opends.server.admin.OperationsException;
/**
 * This exception is thrown when a critical concurrent modification is
 * detected by the client. This may be caused by another client
 * application removing a managed object whilst it is being managed.
 */
public class ConcurrentModificationException extends OperationsException {
  /**
   * Serialization ID.
   */
  private static final long serialVersionUID = -1467024486347612820L;
  /**
   * Create a concurrent modification exception.
   */
  public ConcurrentModificationException() {
    // No implementation required.
  }
  /**
   * Create a concurrent modification exception with a cause.
   *
   * @param cause
   *          The cause.
   */
  public ConcurrentModificationException(Throwable cause) {
    super(cause);
  }
  /**
   * Create a concurrent modification exception with a message and
   * cause.
   *
   * @param message
   *          The message.
   * @param cause
   *          The cause.
   */
  public ConcurrentModificationException(String message, Throwable cause) {
    super(message, cause);
  }
  /**
   * Create a concurrent modification exception with a message.
   *
   * @param message
   *          The message.
   */
  public ConcurrentModificationException(String message) {
    super(message);
  }
}
opendj-sdk/opends/src/server/org/opends/server/admin/client/ExampleClient.java
@@ -30,13 +30,15 @@
import static org.opends.server.loggers.ErrorLogger.*;
import static org.opends.server.util.ServerConstants.PROPERTY_SERVER_ROOT;
import static org.opends.server.util.ServerConstants.*;
import java.io.File;
import org.opends.server.admin.ClassLoaderProvider;
import org.opends.server.admin.AttributeTypePropertyDefinition;
import org.opends.server.admin.ClassLoaderProvider;
import org.opends.server.admin.ClassPropertyDefinition;
import org.opends.server.admin.client.ldap.JNDIDirContextAdaptor;
import org.opends.server.admin.client.ldap.LDAPConnection;
import org.opends.server.admin.client.ldap.LDAPManagementContext;
import org.opends.server.admin.std.client.ConnectionHandlerCfgClient;
import org.opends.server.admin.std.client.GlobalCfgClient;
@@ -128,8 +130,9 @@
   * Perform the client operations.
   */
  private void run() throws Exception {
    ManagementContext ctx = LDAPManagementContext.createLDAPContext(
        "localhost", 1389, "cn=directory manager", "password");
    LDAPConnection connection = JNDIDirContextAdaptor.simpleBind("localhost",
        1389, "cn=directory manager", "password");
    ManagementContext ctx = LDAPManagementContext.createFromContext(connection);
    RootCfgClient root = ctx.getRootConfiguration();
opendj-sdk/opends/src/server/org/opends/server/admin/client/InitialManagedObject.java
@@ -92,9 +92,9 @@
    /**
     * {@inheritDoc}
     */
    public Collection<?> getDefaultPropertyValues(
        ManagedObjectPath path, String propertyName)
        throws OperationsException, PropertyNotFoundException {
    public Collection<?> getDefaultPropertyValues(ManagedObjectPath path,
        String propertyName) throws OperationsException,
        PropertyNotFoundException {
      throw new PropertyNotFoundException(propertyName);
    }
@@ -142,7 +142,7 @@
   * This implementation throws an
   * {@link UnsupportedOperationException}.
   */
  public void commit() throws OperationsException {
  public void commit() throws UnsupportedOperationException {
    throw new UnsupportedOperationException();
  }
@@ -156,9 +156,8 @@
   */
  public <M extends ConfigurationClient, N extends M>
      ManagedObject<N> createChild(
      InstantiableRelationDefinition<M, ?> r,
      ManagedObjectDefinition<N, ?> d, String name, PropertyProvider p)
      throws IllegalArgumentException, OperationsException {
      InstantiableRelationDefinition<M, ?> r, ManagedObjectDefinition<N, ?> d,
      String name, PropertyProvider p) throws UnsupportedOperationException {
    throw new UnsupportedOperationException();
  }
@@ -172,9 +171,8 @@
   */
  public <M extends ConfigurationClient, N extends M>
      ManagedObject<N> createChild(
      OptionalRelationDefinition<M, ?> r,
      ManagedObjectDefinition<N, ?> d, PropertyProvider p)
      throws IllegalArgumentException, OperationsException {
      OptionalRelationDefinition<M, ?> r, ManagedObjectDefinition<N, ?> d,
      PropertyProvider p) throws UnsupportedOperationException {
    throw new UnsupportedOperationException();
  }
@@ -188,7 +186,7 @@
   */
  public <M extends ConfigurationClient> ManagedObject<? extends M> getChild(
      InstantiableRelationDefinition<M, ?> d, String name)
      throws IllegalArgumentException, OperationsException {
      throws UnsupportedOperationException {
    throw new UnsupportedOperationException();
  }
@@ -201,8 +199,7 @@
   * {@link UnsupportedOperationException}.
   */
  public <M extends ConfigurationClient> ManagedObject<? extends M> getChild(
      OptionalRelationDefinition<M, ?> d)
      throws IllegalArgumentException, OperationsException {
      OptionalRelationDefinition<M, ?> d) throws UnsupportedOperationException {
    throw new UnsupportedOperationException();
  }
@@ -216,7 +213,7 @@
   */
  public <M extends ConfigurationClient> ManagedObject<? extends M> getChild(
      SingletonRelationDefinition<M, ?> d)
      throws IllegalArgumentException, OperationsException {
      throws UnsupportedOperationException {
    throw new UnsupportedOperationException();
  }
@@ -279,7 +276,7 @@
   * {@link UnsupportedOperationException}.
   */
  public boolean hasChild(OptionalRelationDefinition<?, ?> d)
      throws IllegalArgumentException, OperationsException {
      throws UnsupportedOperationException {
    throw new UnsupportedOperationException();
  }
@@ -292,7 +289,7 @@
   * {@link UnsupportedOperationException}.
   */
  public String[] listChildren(InstantiableRelationDefinition<?, ?> d)
      throws IllegalArgumentException, OperationsException {
      throws UnsupportedOperationException {
    throw new UnsupportedOperationException();
  }
@@ -306,7 +303,7 @@
   */
  public <M extends ConfigurationClient> void removeChild(
      InstantiableRelationDefinition<M, ?> d, String name)
      throws IllegalArgumentException, OperationsException {
      throws UnsupportedOperationException {
    throw new UnsupportedOperationException();
  }
@@ -319,8 +316,7 @@
   * {@link UnsupportedOperationException}.
   */
  public <M extends ConfigurationClient> void removeChild(
      OptionalRelationDefinition<M, ?> d)
      throws IllegalArgumentException, OperationsException {
      OptionalRelationDefinition<M, ?> d) throws UnsupportedOperationException {
    throw new UnsupportedOperationException();
  }
@@ -331,9 +327,8 @@
   * {@inheritDoc}
   */
  public <T> void setPropertyValue(PropertyDefinition<T> d, T value)
      throws IllegalPropertyValueException,
      PropertyIsReadOnlyException, PropertyIsMandatoryException,
      IllegalArgumentException {
      throws IllegalPropertyValueException, PropertyIsReadOnlyException,
      PropertyIsMandatoryException, IllegalArgumentException {
    properties.setPropertyValue(d, value);
  }
opendj-sdk/opends/src/server/org/opends/server/admin/client/ManagedObject.java
@@ -32,12 +32,14 @@
import java.util.Collection;
import java.util.SortedSet;
import org.opends.server.admin.DefinitionDecodingException;
import org.opends.server.admin.IllegalPropertyValueException;
import org.opends.server.admin.InstantiableRelationDefinition;
import org.opends.server.admin.ManagedObjectAlreadyExistsException;
import org.opends.server.admin.ManagedObjectDefinition;
import org.opends.server.admin.ConfigurationClient;
import org.opends.server.admin.ManagedObjectNotFoundException;
import org.opends.server.admin.ManagedObjectPath;
import org.opends.server.admin.OperationsException;
import org.opends.server.admin.OptionalRelationDefinition;
import org.opends.server.admin.PropertyDefinition;
import org.opends.server.admin.PropertyIsMandatoryException;
@@ -89,117 +91,6 @@
    PropertyProvider {
  /**
   * Get the effective value of the specified property.
   * <p>
   * See the class description for more information about how the
   * effective property value is derived.
   *
   * @param <T>
   *          The type of the property to be retrieved.
   * @param d
   *          The property to be retrieved.
   * @return Returns the property's effective value, or
   *         <code>null</code> if there is no effective value
   *         defined.
   * @throws IllegalArgumentException
   *           If the property definition is not associated with this
   *           managed object's definition.
   */
  public <T> T getPropertyValue(PropertyDefinition<T> d)
      throws IllegalArgumentException;
  /**
   * Get the effective values of the specified property.
   * <p>
   * See the class description for more information about how the
   * effective property values are derived.
   *
   * @param <T>
   *          The type of the property to be retrieved.
   * @param d
   *          The property to be retrieved.
   * @return Returns the property's effective values, or an empty set
   *         if there are no effective values defined.
   * @throws IllegalArgumentException
   *           If the property definition is not associated with this
   *           managed object's definition.
   */
  public <T> SortedSet<T> getPropertyValues(PropertyDefinition<T> d)
      throws IllegalArgumentException;
  /**
   * Set a new pending value for the specified property.
   * <p>
   * See the class description for more information regarding pending
   * values.
   *
   * @param <T>
   *          The type of the property to be modified.
   * @param d
   *          The property to be modified.
   * @param value
   *          The new pending value for the property, or
   *          <code>null</code> if the property should be reset to
   *          its default behavior.
   * @throws IllegalPropertyValueException
   *           If the new pending value is deemed to be invalid
   *           according to the property definition.
   * @throws PropertyIsReadOnlyException
   *           If an attempt was made to modify a read-only property.
   * @throws PropertyIsMandatoryException
   *           If an attempt was made to remove a mandatory property.
   * @throws IllegalArgumentException
   *           If the specified property definition is not associated
   *           with this managed object.
   */
  public <T> void setPropertyValue(PropertyDefinition<T> d, T value)
      throws IllegalPropertyValueException,
      PropertyIsReadOnlyException, PropertyIsMandatoryException,
      IllegalArgumentException;
  /**
   * Set a new pending values for the specified property.
   * <p>
   * See the class description for more information regarding pending
   * values.
   *
   * @param <T>
   *          The type of the property to be modified.
   * @param d
   *          The property to be modified.
   * @param values
   *          A non-<code>null</code> set of new pending values for
   *          the property (an empty set indicates that the property
   *          should be reset to its default behavior). The set will
   *          not be referenced by this managed object.
   * @throws IllegalPropertyValueException
   *           If a new pending value is deemed to be invalid
   *           according to the property definition.
   * @throws PropertyIsSingleValuedException
   *           If an attempt was made to add multiple pending values
   *           to a single-valued property.
   * @throws PropertyIsReadOnlyException
   *           If an attempt was made to modify a read-only property.
   * @throws PropertyIsMandatoryException
   *           If an attempt was made to remove a mandatory property.
   * @throws IllegalArgumentException
   *           If the specified property definition is not associated
   *           with this managed object.
   */
  public <T> void setPropertyValues(PropertyDefinition<T> d,
      Collection<T> values) throws IllegalPropertyValueException,
      PropertyIsSingleValuedException, PropertyIsReadOnlyException,
      PropertyIsMandatoryException, IllegalArgumentException;
  /**
   * Commit any changes made to this managed object. Pending property
   * values will be committed to the managed object. If successful,
   * the pending values will become active values.
@@ -207,11 +98,22 @@
   * See the class description for more information regarding pending
   * and active values.
   *
   * @throws OperationsException
   *           If the changes to this managed object could not be
   *           committed due to some underlying communication problem.
   * @throws ConcurrentModificationException
   *           If this managed object has been removed from the server
   *           by another client.
   * @throws OperationRejectedException
   *           If the server refuses to apply the changes due to some
   *           server-side constraint which cannot be satisfied.
   * @throws AuthorizationException
   *           If the server refuses to apply the changes because the
   *           client does not have the correct privileges.
   * @throws CommunicationException
   *           If the client cannot contact the server due to an
   *           underlying communication problem.
   */
  void commit() throws OperationsException;
  void commit() throws ConcurrentModificationException,
      OperationRejectedException, AuthorizationException,
      CommunicationException;
@@ -242,14 +144,33 @@
   * @throws IllegalArgumentException
   *           If the relation definition is not associated with this
   *           managed object's definition.
   * @throws OperationsException
   *           If the managed object could not be created due to some
   * @throws ManagedObjectDecodingException
   *           If the managed object could not be create because one
   *           or more of its properties are invalid.
   * @throws ManagedObjectAlreadyExistsException
   *           If the managed object cannot be created because it
   *           already exists on the server.
   * @throws ConcurrentModificationException
   *           If this managed object has been removed from the server
   *           by another client.
   * @throws OperationRejectedException
   *           If the server refuses to create the managed object due
   *           to some server-side constraint which cannot be
   *           satisfied.
   * @throws AuthorizationException
   *           If the server refuses to create the managed object
   *           because the client does not have the correct
   *           privileges.
   * @throws CommunicationException
   *           If the client cannot contact the server due to an
   *           underlying communication problem.
   */
  <M extends ConfigurationClient, N extends M> ManagedObject<N> createChild(
      InstantiableRelationDefinition<M, ?> r,
      ManagedObjectDefinition<N, ?> d, String name, PropertyProvider p)
      throws IllegalArgumentException, OperationsException;
      InstantiableRelationDefinition<M, ?> r, ManagedObjectDefinition<N, ?> d,
      String name, PropertyProvider p) throws IllegalArgumentException,
      ManagedObjectDecodingException, ManagedObjectAlreadyExistsException,
      ConcurrentModificationException, OperationRejectedException,
      AuthorizationException, CommunicationException;
@@ -278,14 +199,33 @@
   * @throws IllegalArgumentException
   *           If the relation definition is not associated with this
   *           managed object's definition.
   * @throws OperationsException
   *           If the managed object could not be created due to some
   * @throws ManagedObjectDecodingException
   *           If the managed object could not be created because one
   *           or more of its properties are invalid.
   * @throws ManagedObjectAlreadyExistsException
   *           If the managed object cannot be created because it
   *           already exists on the server.
   * @throws ConcurrentModificationException
   *           If this managed object has been removed from the server
   *           by another client.
   * @throws OperationRejectedException
   *           If the server refuses to create the managed object due
   *           to some server-side constraint which cannot be
   *           satisfied.
   * @throws AuthorizationException
   *           If the server refuses to create the managed object
   *           because the client does not have the correct
   *           privileges.
   * @throws CommunicationException
   *           If the client cannot contact the server due to an
   *           underlying communication problem.
   */
  <M extends ConfigurationClient, N extends M> ManagedObject<N> createChild(
      OptionalRelationDefinition<M, ?> r,
      ManagedObjectDefinition<N, ?> d, PropertyProvider p)
      throws IllegalArgumentException, OperationsException;
      OptionalRelationDefinition<M, ?> r, ManagedObjectDefinition<N, ?> d,
      PropertyProvider p) throws IllegalArgumentException,
      ManagedObjectDecodingException, ManagedObjectAlreadyExistsException,
      ConcurrentModificationException, OperationRejectedException,
      AuthorizationException, CommunicationException;
@@ -303,13 +243,32 @@
   * @throws IllegalArgumentException
   *           If the relation definition is not associated with this
   *           managed object's definition.
   * @throws OperationsException
   *           If the managed object could not be read due to some
   * @throws DefinitionDecodingException
   *           If the managed object was found but its type could not
   *           be determined.
   * @throws ManagedObjectDecodingException
   *           If the managed object was found but one or more of its
   *           properties could not be decoded.
   * @throws ManagedObjectNotFoundException
   *           If the requested managed object could not be found on
   *           the server.
   * @throws ConcurrentModificationException
   *           If this managed object has been removed from the server
   *           by another client.
   * @throws AuthorizationException
   *           If the server refuses to retrieve the managed object
   *           because the client does not have the correct
   *           privileges.
   * @throws CommunicationException
   *           If the client cannot contact the server due to an
   *           underlying communication problem.
   */
  <M extends ConfigurationClient> ManagedObject<? extends M> getChild(
      InstantiableRelationDefinition<M, ?> d, String name)
      throws IllegalArgumentException, OperationsException;
      throws IllegalArgumentException, DefinitionDecodingException,
      ManagedObjectDecodingException, ManagedObjectNotFoundException,
      ConcurrentModificationException, AuthorizationException,
      CommunicationException;
@@ -325,13 +284,31 @@
   * @throws IllegalArgumentException
   *           If the relation definition is not associated with this
   *           managed object's definition.
   * @throws OperationsException
   *           If the managed object could not be read due to some
   * @throws DefinitionDecodingException
   *           If the managed object was found but its type could not
   *           be determined.
   * @throws ManagedObjectDecodingException
   *           If the managed object was found but one or more of its
   *           properties could not be decoded.
   * @throws ManagedObjectNotFoundException
   *           If the requested managed object could not be found on
   *           the server.
   * @throws ConcurrentModificationException
   *           If this managed object has been removed from the server
   *           by another client.
   * @throws AuthorizationException
   *           If the server refuses to retrieve the managed object
   *           because the client does not have the correct
   *           privileges.
   * @throws CommunicationException
   *           If the client cannot contact the server due to an
   *           underlying communication problem.
   */
  <M extends ConfigurationClient> ManagedObject<? extends M> getChild(
      OptionalRelationDefinition<M, ?> d)
      throws IllegalArgumentException, OperationsException;
      OptionalRelationDefinition<M, ?> d) throws IllegalArgumentException,
      DefinitionDecodingException, ManagedObjectDecodingException,
      ManagedObjectNotFoundException, ConcurrentModificationException,
      AuthorizationException, CommunicationException;
@@ -347,13 +324,31 @@
   * @throws IllegalArgumentException
   *           If the relation definition is not associated with this
   *           managed object's definition.
   * @throws OperationsException
   *           If the managed object could not be read due to some
   * @throws DefinitionDecodingException
   *           If the managed object was found but its type could not
   *           be determined.
   * @throws ManagedObjectDecodingException
   *           If the managed object was found but one or more of its
   *           properties could not be decoded.
   * @throws ManagedObjectNotFoundException
   *           If the requested managed object could not be found on
   *           the server.
   * @throws ConcurrentModificationException
   *           If this managed object has been removed from the server
   *           by another client.
   * @throws AuthorizationException
   *           If the server refuses to retrieve the managed object
   *           because the client does not have the correct
   *           privileges.
   * @throws CommunicationException
   *           If the client cannot contact the server due to an
   *           underlying communication problem.
   */
  <M extends ConfigurationClient> ManagedObject<? extends M> getChild(
      SingletonRelationDefinition<M, ?> d)
      throws IllegalArgumentException, OperationsException;
      SingletonRelationDefinition<M, ?> d) throws IllegalArgumentException,
      DefinitionDecodingException, ManagedObjectDecodingException,
      ManagedObjectNotFoundException, ConcurrentModificationException,
      AuthorizationException, CommunicationException;
@@ -389,6 +384,49 @@
  /**
   * Get the effective value of the specified property.
   * <p>
   * See the class description for more information about how the
   * effective property value is derived.
   *
   * @param <T>
   *          The type of the property to be retrieved.
   * @param d
   *          The property to be retrieved.
   * @return Returns the property's effective value, or
   *         <code>null</code> if there is no effective value
   *         defined.
   * @throws IllegalArgumentException
   *           If the property definition is not associated with this
   *           managed object's definition.
   */
  <T> T getPropertyValue(PropertyDefinition<T> d)
      throws IllegalArgumentException;
  /**
   * Get the effective values of the specified property.
   * <p>
   * See the class description for more information about how the
   * effective property values are derived.
   *
   * @param <T>
   *          The type of the property to be retrieved.
   * @param d
   *          The property to be retrieved.
   * @return Returns the property's effective values, or an empty set
   *         if there are no effective values defined.
   * @throws IllegalArgumentException
   *           If the property definition is not associated with this
   *           managed object's definition.
   */
  <T> SortedSet<T> getPropertyValues(PropertyDefinition<T> d)
      throws IllegalArgumentException;
  /**
   * Determines whether or not the optional managed object associated
   * with the specified optional relations exists.
   *
@@ -399,13 +437,19 @@
   * @throws IllegalArgumentException
   *           If the relation definition is not associated with this
   *           managed object's definition.
   * @throws OperationsException
   *           If the existance of the optional managed object could
   *           not be determined due to some underlying communication
   *           problem.
   * @throws ConcurrentModificationException
   *           If this managed object has been removed from the server
   *           by another client.
   * @throws AuthorizationException
   *           If the server refuses to make the determination because
   *           the client does not have the correct privileges.
   * @throws CommunicationException
   *           If the client cannot contact the server due to an
   *           underlying communication problem.
   */
  boolean hasChild(OptionalRelationDefinition<?, ?> d)
      throws IllegalArgumentException, OperationsException;
      throws IllegalArgumentException, ConcurrentModificationException,
      AuthorizationException, CommunicationException;
@@ -419,12 +463,20 @@
   * @throws IllegalArgumentException
   *           If the relation definition is not associated with this
   *           managed object's definition.
   * @throws OperationsException
   *           If the managed objects could not be listed due to some
   * @throws ConcurrentModificationException
   *           If this managed object has been removed from the server
   *           by another client.
   * @throws AuthorizationException
   *           If the server refuses to list the managed objects
   *           because the client does not have the correct
   *           privileges.
   * @throws CommunicationException
   *           If the client cannot contact the server due to an
   *           underlying communication problem.
   */
  String[] listChildren(InstantiableRelationDefinition<?, ?> d)
      throws IllegalArgumentException, OperationsException;
      throws IllegalArgumentException, ConcurrentModificationException,
      AuthorizationException, CommunicationException;
@@ -441,13 +493,30 @@
   * @throws IllegalArgumentException
   *           If the relation definition is not associated with this
   *           managed object's definition.
   * @throws OperationsException
   *           If the managed object could not be removed due to some
   * @throws ManagedObjectNotFoundException
   *           If the managed object could not be removed because it
   *           could not found on the server.
   * @throws OperationRejectedException
   *           If the server refuses to remove the managed object due
   *           to some server-side constraint which cannot be
   *           satisfied (for example, if it is referenced by another
   *           managed object).
   * @throws ConcurrentModificationException
   *           If this managed object has been removed from the server
   *           by another client.
   * @throws AuthorizationException
   *           If the server refuses to make the list the managed
   *           objects because the client does not have the correct
   *           privileges.
   * @throws CommunicationException
   *           If the client cannot contact the server due to an
   *           underlying communication problem.
   */
  <M extends ConfigurationClient> void removeChild(
      InstantiableRelationDefinition<M, ?> d, String name)
      throws IllegalArgumentException, OperationsException;
      throws IllegalArgumentException, ManagedObjectNotFoundException,
      OperationRejectedException, ConcurrentModificationException,
      AuthorizationException, CommunicationException;
@@ -462,12 +531,96 @@
   * @throws IllegalArgumentException
   *           If the relation definition is not associated with this
   *           managed object's definition.
   * @throws OperationsException
   *           If the managed object could not be removed due to some
   * @throws ManagedObjectNotFoundException
   *           If the managed object could not be removed because it
   *           could not found on the server.
   * @throws OperationRejectedException
   *           If the server refuses to remove the managed object due
   *           to some server-side constraint which cannot be
   *           satisfied (for example, if it is referenced by another
   *           managed object).
   * @throws ConcurrentModificationException
   *           If this managed object has been removed from the server
   *           by another client.
   * @throws AuthorizationException
   *           If the server refuses to make the list the managed
   *           objects because the client does not have the correct
   *           privileges.
   * @throws CommunicationException
   *           If the client cannot contact the server due to an
   *           underlying communication problem.
   */
  <M extends ConfigurationClient> void removeChild(
      OptionalRelationDefinition<M, ?> d)
      throws IllegalArgumentException, OperationsException;
      OptionalRelationDefinition<M, ?> d) throws IllegalArgumentException,
      ManagedObjectNotFoundException, OperationRejectedException,
      ConcurrentModificationException, AuthorizationException,
      CommunicationException;
  /**
   * Set a new pending value for the specified property.
   * <p>
   * See the class description for more information regarding pending
   * values.
   *
   * @param <T>
   *          The type of the property to be modified.
   * @param d
   *          The property to be modified.
   * @param value
   *          The new pending value for the property, or
   *          <code>null</code> if the property should be reset to
   *          its default behavior.
   * @throws IllegalPropertyValueException
   *           If the new pending value is deemed to be invalid
   *           according to the property definition.
   * @throws PropertyIsReadOnlyException
   *           If an attempt was made to modify a read-only property.
   * @throws PropertyIsMandatoryException
   *           If an attempt was made to remove a mandatory property.
   * @throws IllegalArgumentException
   *           If the specified property definition is not associated
   *           with this managed object.
   */
  <T> void setPropertyValue(PropertyDefinition<T> d, T value)
      throws IllegalPropertyValueException, PropertyIsReadOnlyException,
      PropertyIsMandatoryException, IllegalArgumentException;
  /**
   * Set a new pending values for the specified property.
   * <p>
   * See the class description for more information regarding pending
   * values.
   *
   * @param <T>
   *          The type of the property to be modified.
   * @param d
   *          The property to be modified.
   * @param values
   *          A non-<code>null</code> set of new pending values for
   *          the property (an empty set indicates that the property
   *          should be reset to its default behavior). The set will
   *          not be referenced by this managed object.
   * @throws IllegalPropertyValueException
   *           If a new pending value is deemed to be invalid
   *           according to the property definition.
   * @throws PropertyIsSingleValuedException
   *           If an attempt was made to add multiple pending values
   *           to a single-valued property.
   * @throws PropertyIsReadOnlyException
   *           If an attempt was made to modify a read-only property.
   * @throws PropertyIsMandatoryException
   *           If an attempt was made to remove a mandatory property.
   * @throws IllegalArgumentException
   *           If the specified property definition is not associated
   *           with this managed object.
   */
  <T> void setPropertyValues(PropertyDefinition<T> d, Collection<T> values)
      throws IllegalPropertyValueException, PropertyIsSingleValuedException,
      PropertyIsReadOnlyException, PropertyIsMandatoryException,
      IllegalArgumentException;
}
opendj-sdk/opends/src/server/org/opends/server/admin/client/OperationRejectedException.java
New file
@@ -0,0 +1,94 @@
/*
 * 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/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * 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/opends/resource/legal-notices/OpenDS.LICENSE.  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
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.server.admin.client;
/**
 * This exception is thrown when the server refuses to create, delete,
 * or modify a managed object due to some server-side constraint that
 * cannot be satisified and which cannot be enforced by the client.
 * <p>
 * For example, the Directory Server might not be able perform an
 * operation due to some OS related problem, such as lack of disk
 * space, or missing files.
 */
public class OperationRejectedException extends AdminClientException {
  /**
   * Serialization ID.
   */
  private static final long serialVersionUID = 8547688890613079044L;
  /**
   * Create an operation rejected exception.
   */
  public OperationRejectedException() {
    // No implementation required.
  }
  /**
   * Create an operation rejected exception with a cause.
   *
   * @param cause
   *          The cause.
   */
  public OperationRejectedException(Throwable cause) {
    super(cause);
  }
  /**
   * Create an operation rejected exception with a message and cause.
   *
   * @param message
   *          The message.
   * @param cause
   *          The cause.
   */
  public OperationRejectedException(String message, Throwable cause) {
    super(message, cause);
  }
  /**
   * Create an operation rejected exception with a message.
   *
   * @param message
   *          The message.
   */
  public OperationRejectedException(String message) {
    super(message);
  }
}
opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/JNDIDirContextAdaptor.java
New file
@@ -0,0 +1,239 @@
/*
 * 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/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * 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/opends/resource/legal-notices/OpenDS.LICENSE.  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
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.server.admin.client.ldap;
import java.util.Collection;
import java.util.Hashtable;
import java.util.LinkedList;
import java.util.List;
import javax.naming.Context;
import javax.naming.NameNotFoundException;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.ModificationItem;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapName;
import javax.naming.ldap.Rdn;
import org.opends.server.admin.client.AuthenticationException;
import org.opends.server.admin.client.AuthenticationNotSupportedException;
import org.opends.server.admin.client.CommunicationException;
/**
 * An LDAP connection JNDI connection adaptor. This maps LDAP requests
 * onto an underlying JNDI connection context.
 */
public final class JNDIDirContextAdaptor extends LDAPConnection {
  /**
   * Adapts the provided JNDI <code>DirContext</code>.
   *
   * @param dirContext
   *          The JNDI connection.
   * @return Returns a new JNDI connection adaptor.
   */
  public static JNDIDirContextAdaptor adapt(DirContext dirContext) {
    return new JNDIDirContextAdaptor(dirContext);
  }
  /**
   * Creates a new JNDI connection adaptor by performing a simple bind
   * operation to the specified LDAP server.
   *
   * @param host
   *          The host.
   * @param port
   *          The port.
   * @param name
   *          The LDAP bind DN.
   * @param password
   *          The LDAP bind password.
   * @return Returns a new JNDI connection adaptor.
   * @throws CommunicationException
   *           If the client cannot contact the server due to an
   *           underlying communication problem.
   * @throws AuthenticationNotSupportedException
   *           If the server does not support simple authentication.
   * @throws AuthenticationException
   *           If authentication failed for some reason, usually due
   *           to invalid credentials.
   */
  public static JNDIDirContextAdaptor simpleBind(String host, int port,
      String name, String password) throws CommunicationException,
      AuthenticationNotSupportedException, AuthenticationException {
    Hashtable<String, Object> env = new Hashtable<String, Object>();
    env
        .put(Context.INITIAL_CONTEXT_FACTORY,
            "com.sun.jndi.ldap.LdapCtxFactory");
    env.put(Context.PROVIDER_URL, "ldap://" + host + ":" + port);
    env.put(Context.SECURITY_PRINCIPAL, name);
    env.put(Context.SECURITY_CREDENTIALS, password);
    DirContext ctx;
    try {
      ctx = new InitialLdapContext(env, null);
    } catch (javax.naming.CommunicationException e) {
      throw new CommunicationException(e);
    } catch (javax.naming.AuthenticationException e) {
      throw new AuthenticationException(e);
    } catch (javax.naming.AuthenticationNotSupportedException e) {
      throw new AuthenticationNotSupportedException(e);
    } catch (NamingException e) {
      // Assume some kind of communication problem.
      throw new CommunicationException(e);
    }
    return new JNDIDirContextAdaptor(ctx);
  }
  // The JNDI connection context.
  private final DirContext dirContext;
  // Create a new JNDI connection adaptor using the provider JNDI
  // DirContext.
  private JNDIDirContextAdaptor(DirContext dirContext) {
    this.dirContext = dirContext;
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public void createEntry(LdapName dn, Attributes attributes)
      throws NamingException {
    dirContext.createSubcontext(dn, attributes);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public void deleteSubtree(LdapName dn) throws NamingException {
    // Delete the children first.
    for (LdapName child : listEntries(dn)) {
      deleteSubtree(child);
    }
    // Delete the named entry.
    dirContext.destroySubcontext(dn);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public boolean entryExists(LdapName dn) throws NamingException {
    String filter = "(objectClass=*)";
    SearchControls controls = new SearchControls();
    controls.setSearchScope(SearchControls.OBJECT_SCOPE);
    try {
      NamingEnumeration<SearchResult> results = dirContext.search(dn, filter,
          controls);
      if (results.hasMore()) {
        return true;
      }
    } catch (NameNotFoundException e) {
      // Fall through - entry not found.
    }
    return false;
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public Collection<LdapName> listEntries(LdapName dn) throws NamingException {
    String filter = "(objectClass=*)";
    SearchControls controls = new SearchControls();
    controls.setSearchScope(SearchControls.ONELEVEL_SCOPE);
    List<LdapName> children = new LinkedList<LdapName>();
    NamingEnumeration<SearchResult> results = dirContext.search(dn, filter,
        controls);
    while (results.hasMore()) {
      SearchResult sr = results.next();
      LdapName child = new LdapName(dn.getRdns());
      child.add(new Rdn(sr.getName()));
      children.add(child);
    }
    return children;
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public void modifyEntry(LdapName dn, Attributes mods) throws NamingException {
    ModificationItem[] modList = new ModificationItem[mods.size()];
    NamingEnumeration<? extends Attribute> ne = mods.getAll();
    for (int i = 0; ne.hasMore(); i++) {
      ModificationItem modItem = new ModificationItem(
          DirContext.REPLACE_ATTRIBUTE, ne.next());
      modList[i] = modItem;
    }
    dirContext.modifyAttributes(dn, modList);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public Attributes readEntry(LdapName dn, Collection<String> attrIds)
      throws NamingException {
    String[] attrIdList = attrIds.toArray(new String[attrIds.size()]);
    return dirContext.getAttributes(dn, attrIdList);
  }
}
opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPChangeBuilder.java
File was deleted
opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPConnection.java
New file
@@ -0,0 +1,140 @@
/*
 * 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/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * 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/opends/resource/legal-notices/OpenDS.LICENSE.  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
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.server.admin.client.ldap;
import java.util.Collection;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.naming.ldap.LdapName;
/**
 * A client connection which is used to perform JNDI-based LDAP
 * operations.
 * <p>
 * This interface is provided in order to make it easier to keep track
 * of which JNDI DirContext methods we require and also to facilitate
 * implementation of mock JNDI contexts for unit-testing.
 */
public abstract class LDAPConnection {
  /**
   * Create a new LDAP connection.
   */
  protected LDAPConnection() {
    // No implementation required.
  }
  /**
   * Creates a new entry with the specified set of attributes.
   *
   * @param dn
   *          The name of the entry to be created.
   * @param attributes
   *          The set of attributes.
   * @throws NamingException
   *           If an error occurred whilst creating the entry.
   */
  public abstract void createEntry(LdapName dn, Attributes attributes)
      throws NamingException;
  /**
   * Deletes the named subtree.
   *
   * @param dn
   *          The name of the subtree to be deleted.
   * @throws NamingException
   *           If an error occurred whilst deleting the subtree.
   */
  public abstract void deleteSubtree(LdapName dn) throws NamingException;
  /**
   * Determines whether or not the named entry exists.
   *
   * @param dn
   *          The name of the entry.
   * @return Returns <code>true</code> if the entry exists.
   * @throws NamingException
   *           If an error occurred whilst making the determination.
   */
  public abstract boolean entryExists(LdapName dn) throws NamingException;
  /**
   * Lists the children of the named entry.
   *
   * @param dn
   *          The name of the entry to list.
   * @return Returns the names of the children.
   * @throws NamingException
   *           If an error occurred whilst listing the children.
   */
  public abstract Collection<LdapName> listEntries(LdapName dn)
      throws NamingException;
  /**
   * Modifies the attributes of the named entry.
   *
   * @param dn
   *          The name of the entry to be modified.
   * @param mods
   *          The list of attributes which need replacing.
   * @throws NamingException
   *           If an error occurred whilst applying the modifications.
   */
  public abstract void modifyEntry(LdapName dn, Attributes mods)
      throws NamingException;
  /**
   * Reads the attributes of the named entry.
   *
   * @param dn
   *          The name of the entry to be read.
   * @param attrIds
   *          The list of attributes to be retrievd.
   * @return Returns the attributes of the requested entry.
   * @throws NamingException
   *           If an error occurred whilst reading the entry.
   */
  public abstract Attributes readEntry(LdapName dn, Collection<String> attrIds)
      throws NamingException;
}
opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagedObject.java
@@ -31,22 +31,23 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.SortedSet;
import javax.naming.NameAlreadyBoundException;
import javax.naming.NameNotFoundException;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.NoPermissionException;
import javax.naming.OperationNotSupportedException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.BasicAttributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.LdapName;
import javax.naming.ldap.Rdn;
@@ -57,8 +58,9 @@
import org.opends.server.admin.IllegalPropertyValueException;
import org.opends.server.admin.InheritedDefaultValueProvider;
import org.opends.server.admin.InstantiableRelationDefinition;
import org.opends.server.admin.LDAPProfile;
import org.opends.server.admin.ManagedObjectAlreadyExistsException;
import org.opends.server.admin.ManagedObjectDefinition;
import org.opends.server.admin.ManagedObjectNotFoundException;
import org.opends.server.admin.ManagedObjectPath;
import org.opends.server.admin.OperationsException;
import org.opends.server.admin.OptionalRelationDefinition;
@@ -73,8 +75,12 @@
import org.opends.server.admin.SingletonRelationDefinition;
import org.opends.server.admin.StringPropertyProvider;
import org.opends.server.admin.DefinitionDecodingException.Reason;
import org.opends.server.admin.client.AuthorizationException;
import org.opends.server.admin.client.CommunicationException;
import org.opends.server.admin.client.ConcurrentModificationException;
import org.opends.server.admin.client.ManagedObject;
import org.opends.server.admin.client.ManagedObjectDecodingException;
import org.opends.server.admin.client.OperationRejectedException;
import org.opends.server.admin.client.Property;
import org.opends.server.admin.client.PropertySet;
import org.opends.server.admin.std.client.RootCfgClient;
@@ -89,8 +95,8 @@
 *          The type of client configuration represented by the client
 *          managed object.
 */
final class LDAPManagedObject<C extends ConfigurationClient>
    implements ManagedObject<C> {
final class LDAPManagedObject<C extends ConfigurationClient> implements
    ManagedObject<C> {
  /**
   * Internal inherited default value provider implementation.
@@ -98,25 +104,25 @@
  private static class MyInheritedDefaultValueProvider implements
      InheritedDefaultValueProvider {
    // The LDAP management context.
    private final LDAPManagementContext context;
    // The base path.
    private final ManagedObjectPath path;
    // The LDAP connection context.
    private final DirContext dirContext;
    /**
     * Create a new inherited default value provider.
     *
     * @param dirContext
     *          The LDAP connection context.
     * @param context
     *          The LDAP management context.
     * @param path
     *          The base path.
     */
    public MyInheritedDefaultValueProvider(DirContext dirContext,
    public MyInheritedDefaultValueProvider(LDAPManagementContext context,
        ManagedObjectPath path) {
      this.dirContext = dirContext;
      this.context = context;
      this.path = path;
    }
@@ -125,18 +131,22 @@
    /**
     * {@inheritDoc}
     */
    public Collection<?> getDefaultPropertyValues(
        ManagedObjectPath path, String propertyName)
        throws OperationsException, PropertyNotFoundException {
    public Collection<?> getDefaultPropertyValues(ManagedObjectPath path,
        String propertyName) throws OperationsException,
        PropertyNotFoundException {
      ManagedObjectPath<?, ?> tmp = path;
      ManagedObject<?> mo = readEntry(dirContext, tmp, tmp
          .getManagedObjectDefinition());
      ManagedObjectDefinition<?, ?> mod = mo
          .getManagedObjectDefinition();
      ManagedObject<?> mo;
      try {
        mo = readEntry(context, tmp, tmp.getManagedObjectDefinition());
      } catch (AuthorizationException e) {
        throw new OperationsException(e);
      } catch (CommunicationException e) {
        throw new OperationsException(e);
      }
      ManagedObjectDefinition<?, ?> mod = mo.getManagedObjectDefinition();
      try {
        PropertyDefinition<?> dpd = mod
            .getPropertyDefinition(propertyName);
        PropertyDefinition<?> dpd = mod.getPropertyDefinition(propertyName);
        return mo.getPropertyValues(dpd);
      } catch (IllegalArgumentException e) {
        throw new PropertyNotFoundException(propertyName);
@@ -159,19 +169,18 @@
   * Construct a root LDAP managed object associated with the provided
   * LDAP context.
   *
   * @param dirContext
   *          The LDAP directory context.
   * @param context
   *          The LDAP management context.
   * @return Returns a root LDAP managed object associated with the
   *         provided LDAP context.
   */
  static ManagedObject<RootCfgClient> getRootManagedObject(
      DirContext dirContext) {
      LDAPManagementContext context) {
    List<PropertyException> exceptions = new LinkedList<PropertyException>();
    InheritedDefaultValueProvider i = new MyInheritedDefaultValueProvider(
        dirContext, ManagedObjectPath.emptyPath());
    PropertySet properties = PropertySet.create(RootCfgDefn
        .getInstance(), PropertyProvider.DEFAULT_PROVIDER, i,
        exceptions);
        context, ManagedObjectPath.emptyPath());
    PropertySet properties = PropertySet.create(RootCfgDefn.getInstance(),
        PropertyProvider.DEFAULT_PROVIDER, i, exceptions);
    // Should never get any exceptions.
    if (!exceptions.isEmpty()) {
@@ -179,37 +188,18 @@
          "Got exceptions when creating root managed object");
    }
    return new LDAPManagedObject<RootCfgClient>(dirContext,
        RootCfgDefn.getInstance(), ManagedObjectPath.emptyPath(),
        properties);
    return new LDAPManagedObject<RootCfgClient>(context, RootCfgDefn
        .getInstance(), ManagedObjectPath.emptyPath(), properties);
  }
  // Create a new child LDAP managed object.
  private static <M extends ConfigurationClient>
    ManagedObject<M> createLDAPManagedObject(
      DirContext dirContext, ManagedObjectDefinition<M, ?> d,
      ManagedObject<M> createLDAPManagedObject(
      LDAPManagementContext context, ManagedObjectDefinition<M, ?> d,
      ManagedObjectPath p, PropertySet properties) {
    return new LDAPManagedObject<M>(dirContext, d, p, properties);
  }
  // Get an array containing the list of LDAP attributes names
  // associated with a
  // managed object definition.
  private static String[] getAttributeNames(
      ManagedObjectDefinition<?, ?> d) {
    ArrayList<String> attrIds = new ArrayList<String>();
    for (PropertyDefinition<?> pd : d.getAllPropertyDefinitions()) {
      String attrId = LDAPProfile.getInstance().getAttributeName(d,
          pd);
      attrIds.add(attrId);
    }
    return attrIds.toArray(new String[attrIds.size()]);
    return new LDAPManagedObject<M>(context, d, p, properties);
  }
@@ -218,86 +208,85 @@
  // entry.
  private static <M extends ConfigurationClient>
      ManagedObjectDefinition<? extends M, ?> getEntryDefinition(
      DirContext dirContext, AbstractManagedObjectDefinition<M, ?> d,
      LdapName dn) throws OperationsException {
    try {
      String[] attrIds = new String[] { "objectclass" };
      Attributes attributes = dirContext.getAttributes(dn, attrIds);
      Attribute oc = attributes.get("objectclass");
      final LDAPManagementContext context,
      AbstractManagedObjectDefinition<M, ?> d, LdapName dn)
      throws NamingException, DefinitionDecodingException {
    Attributes attributes = context.getLDAPConnection().readEntry(dn,
        Collections.singleton("objectclass"));
    Attribute oc = attributes.get("objectclass");
      if (oc == null) {
        // No object classes.
        throw new DefinitionDecodingException(
            Reason.NO_TYPE_INFORMATION);
      }
      final Set<String> objectClasses = new HashSet<String>();
      NamingEnumeration<?> values = oc.getAll();
      while (values.hasMore()) {
        Object value = values.next();
        if (value != null) {
          objectClasses.add(value.toString().toLowerCase().trim());
        }
      }
      if (objectClasses.isEmpty()) {
        // No object classes.
        throw new DefinitionDecodingException(
            Reason.NO_TYPE_INFORMATION);
      }
      // Resolve the appropriate sub-type based on the object classes.
      DefinitionResolver resolver = new DefinitionResolver() {
        public boolean matches(AbstractManagedObjectDefinition<?, ?> d) {
          String objectClass = LDAPProfile.getInstance()
              .getObjectClass(d);
          return objectClasses.contains(objectClass);
        }
      };
      return d.resolveManagedObjectDefinition(resolver);
    } catch (NamingException e) {
      OperationsExceptionFactory oef = new OperationsExceptionFactory();
      throw oef.createException(e);
    if (oc == null) {
      // No object classes.
      throw new DefinitionDecodingException(Reason.NO_TYPE_INFORMATION);
    }
    final Set<String> objectClasses = new HashSet<String>();
    NamingEnumeration<?> values = oc.getAll();
    while (values.hasMore()) {
      Object value = values.next();
      if (value != null) {
        objectClasses.add(value.toString().toLowerCase().trim());
      }
    }
    if (objectClasses.isEmpty()) {
      // No object classes.
      throw new DefinitionDecodingException(Reason.NO_TYPE_INFORMATION);
    }
    // Resolve the appropriate sub-type based on the object classes.
    DefinitionResolver resolver = new DefinitionResolver() {
      public boolean matches(AbstractManagedObjectDefinition<?, ?> d) {
        String objectClass = context.getLDAPProfile().getObjectClass(d);
        return objectClasses.contains(objectClass);
      }
    };
    return d.resolveManagedObjectDefinition(resolver);
  }
  // Read the entry identified by the path and which is a sub-type of
  // the
  // specified definition.
  // the specified definition.
  private static <M extends ConfigurationClient>
      ManagedObject<? extends M> readEntry(
      DirContext dirContext, ManagedObjectPath p,
      final LDAPManagementContext context, ManagedObjectPath p,
      AbstractManagedObjectDefinition<M, ?> d)
      throws OperationsException {
    LdapName dn = LDAPNameBuilder.create(p);
    final ManagedObjectDefinition<? extends M, ?> mod = getEntryDefinition(
        dirContext, d, dn);
    String[] attrIds = getAttributeNames(mod);
      throws DefinitionDecodingException, ManagedObjectDecodingException,
      ManagedObjectNotFoundException, AuthorizationException,
      CommunicationException {
    LdapName dn = LDAPNameBuilder.create(p, context.getLDAPProfile());
    final ManagedObjectDefinition<? extends M, ?> mod;
    final Attributes attributes;
    try {
      attributes = dirContext.getAttributes(dn, attrIds);
      mod = getEntryDefinition(context, d, dn);
      ArrayList<String> attrIds = new ArrayList<String>();
      for (PropertyDefinition<?> pd : mod.getAllPropertyDefinitions()) {
        String attrId = context.getLDAPProfile().getAttributeName(mod, pd);
        attrIds.add(attrId);
      }
      attributes = context.getLDAPConnection().readEntry(dn, attrIds);
    } catch (NameNotFoundException e) {
      throw new ManagedObjectNotFoundException();
    } catch (NoPermissionException e) {
      throw new AuthorizationException(e);
    } catch (NamingException e) {
      OperationsExceptionFactory factory = new OperationsExceptionFactory();
      throw factory.createException(e);
      throw new CommunicationException(e);
    }
    // Create a provider which uses LDAP string representations.
    // TODO: the exception handling is a bit of a hack here.
    final List<OperationsException> oelist =
      new LinkedList<OperationsException>();
    final List<NamingException> nelist = new LinkedList<NamingException>();
    StringPropertyProvider provider = new StringPropertyProvider() {
      public Collection<String> getPropertyValues(
          PropertyDefinition<?> d) throws IllegalArgumentException {
        String attrID = LDAPProfile.getInstance().getAttributeName(
            mod, d);
      public Collection<String> getPropertyValues(PropertyDefinition<?> d)
          throws IllegalArgumentException {
        String attrID = context.getLDAPProfile().getAttributeName(mod, d);
        Attribute attribute = attributes.get(attrID);
        List<String> values = new LinkedList<String>();
@@ -311,8 +300,7 @@
              }
            }
          } catch (NamingException e) {
            OperationsExceptionFactory oef = new OperationsExceptionFactory();
            oelist.add(oef.createException(e));
            nelist.add(e);
          }
        }
@@ -321,23 +309,29 @@
    };
    // There can only be at most one operations exception.
    if (!oelist.isEmpty()) {
      throw oelist.get(0);
    // There can only be at most one exception.
    if (!nelist.isEmpty()) {
      try {
        throw nelist.get(0);
      } catch (NameNotFoundException e) {
        throw new ManagedObjectNotFoundException();
      } catch (NoPermissionException e) {
        throw new AuthorizationException(e);
      } catch (NamingException e) {
        throw new CommunicationException(e);
      }
    }
    // Now decode the properties using the provider.
    List<PropertyException> exceptions = new LinkedList<PropertyException>();
    InheritedDefaultValueProvider i = new MyInheritedDefaultValueProvider(
        dirContext, p);
    PropertySet properties = PropertySet.create(mod, provider, i,
        exceptions);
    ManagedObject<? extends M> mo = createLDAPManagedObject(
        dirContext, mod, p, properties);
        context, p);
    PropertySet properties = PropertySet.create(mod, provider, i, exceptions);
    ManagedObject<? extends M> mo = createLDAPManagedObject(context, mod, p,
        properties);
    // If there were no decoding problems then return the object,
    // otherwise
    // throw an operations exception.
    // otherwise throw an operations exception.
    if (exceptions.isEmpty()) {
      return mo;
    } else {
@@ -345,32 +339,28 @@
    }
  }
  // The JNDI context used for the ldap connection.
  private final DirContext dirContext;
  // The path associated with this managed object.
  private final ManagedObjectPath<?, ?> path;
  // LDAP profile associated with this connection.
  private final LDAPProfile profile;
  // The managed object definition associated with this managed
  // object.
  private final ManagedObjectDefinition<C, ?> definition;
  // The LDAP management context used for the ldap connection.
  private final LDAPManagementContext context;
  // The path associated with this managed object.
  private final ManagedObjectPath<?, ?> path;
  // The managed object's properties.
  private final PropertySet properties;
  // Create an new LDAP managed object with the provided JNDI context.
  private LDAPManagedObject(DirContext dirContext,
  private LDAPManagedObject(LDAPManagementContext context,
      ManagedObjectDefinition<C, ?> d, ManagedObjectPath path,
      PropertySet properties) {
    this.definition = d;
    this.dirContext = dirContext;
    this.context = context;
    this.path = path;
    this.profile = LDAPProfile.getInstance();
    this.properties = properties;
  }
@@ -379,19 +369,37 @@
  /**
   * {@inheritDoc}
   */
  public void commit() throws OperationsException {
  public void commit() throws ConcurrentModificationException,
      OperationRejectedException, AuthorizationException,
      CommunicationException {
    // Build the list of modified attributes.
    ManagedObjectDefinition<C, ?> d = getManagedObjectDefinition();
    LDAPChangeBuilder builder = new LDAPChangeBuilder(dirContext,
        path, d);
    Attributes mods = new BasicAttributes();
    for (PropertyDefinition<?> pd : d.getAllPropertyDefinitions()) {
      // FIXME: should throw an error when there are missing mandatory
      // properties.
      Property<?> p = properties.getProperty(pd);
      if (p.isModified()) {
        builder.addChange(p);
        String attrID = context.getLDAPProfile().getAttributeName(d, pd);
        Attribute attribute = new BasicAttribute(attrID);
        encodeProperty(attribute, pd, properties);
        mods.put(attribute);
      }
    }
    builder.commit();
    // Perform the LDAP modification if something has changed.
    if (mods.size() > 0) {
      try {
        LdapName dn = LDAPNameBuilder.create(path, context.getLDAPProfile());
        context.getLDAPConnection().modifyEntry(dn, mods);
      } catch (NoPermissionException e) {
        throw new AuthorizationException(e);
      } catch (OperationNotSupportedException e) {
        // Unwilling to perform.
        throw new OperationRejectedException(e);
      } catch (NamingException e) {
        // Just treat it as a communication problem.
        throw new CommunicationException(e);
      }
    }
  }
@@ -401,9 +409,11 @@
   */
  public <M extends ConfigurationClient, N extends M>
      ManagedObject<N> createChild(
      InstantiableRelationDefinition<M, ?> r,
      ManagedObjectDefinition<N, ?> d, String name, PropertyProvider p)
      throws IllegalArgumentException, OperationsException {
      InstantiableRelationDefinition<M, ?> r, ManagedObjectDefinition<N, ?> d,
      String name, PropertyProvider p) throws IllegalArgumentException,
      ManagedObjectDecodingException, ManagedObjectAlreadyExistsException,
      ConcurrentModificationException, OperationRejectedException,
      AuthorizationException, CommunicationException {
    validateRelationDefinition(r);
    ManagedObjectPath childPath = path.child(r, name);
@@ -411,43 +421,46 @@
    // First make sure all the properties are valid.
    List<PropertyException> exceptions = new LinkedList<PropertyException>();
    InheritedDefaultValueProvider i = new MyInheritedDefaultValueProvider(
        dirContext, childPath);
        context, childPath);
    PropertySet properties = PropertySet.create(d, p, i, exceptions);
    if (!exceptions.isEmpty()) {
      ManagedObject<N> mo = new LDAPManagedObject<N>(dirContext, d,
          childPath, properties);
      ManagedObject<N> mo = new LDAPManagedObject<N>(context, d, childPath,
          properties);
      throw new ManagedObjectDecodingException(mo, exceptions);
    }
    try {
      // TODO: this implementation does not handle relations which
      // comprise of more than one RDN arc (this will probably never
      // be required anyway).
      LdapName dn = LDAPNameBuilder.create(path, r);
    ensureThisManagedObjectExists();
      if (!entryExists(dn)) {
        // Need to create the child managed object's parent entry i.e.
        // the entry representing the relation itself.
        Attributes attributes = new BasicAttributes();
    // TODO: this implementation does not handle relations which
    // comprise of more than one RDN arc (this will probably never
    // be required anyway).
    LdapName dn = LDAPNameBuilder.create(path, r, context.getLDAPProfile());
    if (!entryExists(dn)) {
      // Need to create the child managed object's parent entry i.e.
      // the entry representing the relation itself.
      Attributes attributes = new BasicAttributes();
        // Create the branch's object class attribute.
        Attribute oc = new BasicAttribute("objectClass");
        for (String objectClass : profile
            .getInstantiableRelationObjectClasses(r)) {
          oc.add(objectClass);
        }
        attributes.put(oc);
        // Create the branch's naming attribute.
        Rdn rdn = dn.getRdn(dn.size() - 1);
        attributes.put(rdn.getType(), rdn.getValue().toString());
        // Create the entry.
        dirContext.createSubcontext(dn, attributes);
      // Create the branch's object class attribute.
      Attribute oc = new BasicAttribute("objectClass");
      for (String objectClass : context.getLDAPProfile()
          .getInstantiableRelationObjectClasses(r)) {
        oc.add(objectClass);
      }
    } catch (NamingException e) {
      OperationsExceptionFactory oef = new OperationsExceptionFactory();
      throw oef.createException(e);
      attributes.put(oc);
      // Create the branch's naming attribute.
      Rdn rdn = dn.getRdn(dn.size() - 1);
      attributes.put(rdn.getType(), rdn.getValue().toString());
      // Create the entry.
      try {
        context.getLDAPConnection().createEntry(dn, attributes);
      } catch (OperationNotSupportedException e) {
        // Unwilling to perform.
        throw new OperationRejectedException(e);
      } catch (NamingException e) {
        adaptNamingException(e);
      }
    }
    return createManagedObject(childPath, d, properties);
@@ -460,9 +473,11 @@
   */
  public <M extends ConfigurationClient, N extends M>
      ManagedObject<N> createChild(
      OptionalRelationDefinition<M, ?> r,
      ManagedObjectDefinition<N, ?> d, PropertyProvider p)
      throws IllegalArgumentException, OperationsException {
      OptionalRelationDefinition<M, ?> r, ManagedObjectDefinition<N, ?> d,
      PropertyProvider p) throws IllegalArgumentException,
      ManagedObjectDecodingException, ManagedObjectAlreadyExistsException,
      ConcurrentModificationException, OperationRejectedException,
      AuthorizationException, CommunicationException {
    validateRelationDefinition(r);
    ManagedObjectPath childPath = path.child(r);
@@ -470,14 +485,16 @@
    // First make sure all the properties are valid.
    List<PropertyException> exceptions = new LinkedList<PropertyException>();
    InheritedDefaultValueProvider i = new MyInheritedDefaultValueProvider(
        dirContext, childPath);
        context, childPath);
    PropertySet properties = PropertySet.create(d, p, i, exceptions);
    if (!exceptions.isEmpty()) {
      ManagedObject<N> mo = new LDAPManagedObject<N>(dirContext, d,
          childPath, properties);
      ManagedObject<N> mo = new LDAPManagedObject<N>(context, d, childPath,
          properties);
      throw new ManagedObjectDecodingException(mo, exceptions);
    }
    ensureThisManagedObjectExists();
    return createManagedObject(childPath, d, properties);
  }
@@ -488,10 +505,13 @@
   */
  public <M extends ConfigurationClient> ManagedObject<? extends M> getChild(
      InstantiableRelationDefinition<M, ?> d, String name)
      throws IllegalArgumentException, OperationsException {
      throws IllegalArgumentException, DefinitionDecodingException,
      ManagedObjectDecodingException, ManagedObjectNotFoundException,
      ConcurrentModificationException, AuthorizationException,
      CommunicationException {
    validateRelationDefinition(d);
    return readEntry(dirContext, path.child(d, name), d
        .getChildDefinition());
    ensureThisManagedObjectExists();
    return readEntry(context, path.child(d, name), d.getChildDefinition());
  }
@@ -500,11 +520,13 @@
   * {@inheritDoc}
   */
  public <M extends ConfigurationClient> ManagedObject<? extends M> getChild(
      OptionalRelationDefinition<M, ?> d)
      throws IllegalArgumentException, OperationsException {
      OptionalRelationDefinition<M, ?> d) throws IllegalArgumentException,
      DefinitionDecodingException, ManagedObjectDecodingException,
      ManagedObjectNotFoundException, ConcurrentModificationException,
      AuthorizationException, CommunicationException {
    validateRelationDefinition(d);
    return readEntry(dirContext, path.child(d), d
        .getChildDefinition());
    ensureThisManagedObjectExists();
    return readEntry(context, path.child(d), d.getChildDefinition());
  }
@@ -513,11 +535,13 @@
   * {@inheritDoc}
   */
  public <M extends ConfigurationClient> ManagedObject<? extends M> getChild(
      SingletonRelationDefinition<M, ?> d)
      throws IllegalArgumentException, OperationsException {
      SingletonRelationDefinition<M, ?> d) throws IllegalArgumentException,
      DefinitionDecodingException, ManagedObjectDecodingException,
      ManagedObjectNotFoundException, ConcurrentModificationException,
      AuthorizationException, CommunicationException {
    validateRelationDefinition(d);
    return readEntry(dirContext, path.child(d), d
        .getChildDefinition());
    ensureThisManagedObjectExists();
    return readEntry(context, path.child(d), d.getChildDefinition());
  }
@@ -573,17 +597,14 @@
   * {@inheritDoc}
   */
  public boolean hasChild(OptionalRelationDefinition<?, ?> d)
      throws IllegalArgumentException, OperationsException {
      throws IllegalArgumentException, ConcurrentModificationException,
      AuthorizationException, CommunicationException {
    validateRelationDefinition(d);
    ensureThisManagedObjectExists();
    ManagedObjectPath p = path.child(d);
    LdapName dn = LDAPNameBuilder.create(p);
    try {
      return entryExists(dn);
    } catch (NamingException e) {
      OperationsExceptionFactory oef = new OperationsExceptionFactory();
      throw oef.createException(e);
    }
    LdapName dn = LDAPNameBuilder.create(p, context.getLDAPProfile());
    return entryExists(dn);
  }
@@ -592,35 +613,25 @@
   * {@inheritDoc}
   */
  public String[] listChildren(InstantiableRelationDefinition<?, ?> d)
      throws IllegalArgumentException, OperationsException {
      throws IllegalArgumentException, ConcurrentModificationException,
      AuthorizationException, CommunicationException {
    validateRelationDefinition(d);
    ensureThisManagedObjectExists();
    LdapName dn = LDAPNameBuilder.create(path, d);
    String filter = profile.getFilter(d.getChildDefinition());
    SearchControls controls = new SearchControls();
    controls.setSearchScope(SearchControls.ONELEVEL_SCOPE);
    List<String> children = new ArrayList<String>();
    LdapName dn = LDAPNameBuilder.create(path, d, context.getLDAPProfile());
    try {
      NamingEnumeration<SearchResult> results;
      results = dirContext.search(dn, filter, controls);
      String rtype = profile.getInstantiableRelationChildRDNType(d);
      List<String> names = new ArrayList<String>();
      while (results.hasMore()) {
        SearchResult sr = results.next();
        Attributes attributes = sr.getAttributes();
        Attribute cn = attributes.get(rtype);
        if (cn != null && cn.get() != null) {
          names.add(cn.get().toString());
        }
      for (LdapName child : context.getLDAPConnection().listEntries(dn)) {
        children.add(child.getRdn(child.size() - 1).getValue().toString());
      }
      return names.toArray(new String[names.size()]);
    } catch (NameNotFoundException e) {
      // Ignore this - it means that the base entry does not exist
      // (which it might not if this managed object has just been
      // created.
    } catch (NamingException e) {
      OperationsExceptionFactory oef = new OperationsExceptionFactory();
      throw oef.createException(e);
      adaptNamingException(e);
    }
    return children.toArray(new String[children.size()]);
  }
@@ -630,9 +641,11 @@
   */
  public <M extends ConfigurationClient> void removeChild(
      InstantiableRelationDefinition<M, ?> d, String name)
      throws IllegalArgumentException, OperationsException {
      throws IllegalArgumentException, ManagedObjectNotFoundException,
      OperationRejectedException, ConcurrentModificationException,
      AuthorizationException, CommunicationException {
    validateRelationDefinition(d);
    ensureThisManagedObjectExists();
    ManagedObjectPath p = path.child(d, name);
    removeManagedObject(p);
  }
@@ -643,10 +656,12 @@
   * {@inheritDoc}
   */
  public <M extends ConfigurationClient> void removeChild(
      OptionalRelationDefinition<M, ?> d)
      throws IllegalArgumentException, OperationsException {
      OptionalRelationDefinition<M, ?> d) throws IllegalArgumentException,
      ManagedObjectNotFoundException, OperationRejectedException,
      ConcurrentModificationException, AuthorizationException,
      CommunicationException {
    validateRelationDefinition(d);
    ensureThisManagedObjectExists();
    ManagedObjectPath p = path.child(d);
    removeManagedObject(p);
  }
@@ -657,9 +672,8 @@
   * {@inheritDoc}
   */
  public <T> void setPropertyValue(PropertyDefinition<T> d, T value)
      throws IllegalPropertyValueException,
      PropertyIsReadOnlyException, PropertyIsMandatoryException,
      IllegalArgumentException {
      throws IllegalPropertyValueException, PropertyIsReadOnlyException,
      PropertyIsMandatoryException, IllegalArgumentException {
    properties.setPropertyValue(d, value);
  }
@@ -677,17 +691,39 @@
  // Adapts a naming exception to an appropriate admin client
  // exception.
  private void adaptNamingException(NamingException ne)
      throws CommunicationException, AuthorizationException {
    try {
      throw ne;
    } catch (javax.naming.CommunicationException e) {
      throw new CommunicationException(e);
    } catch (javax.naming.ServiceUnavailableException e) {
      throw new CommunicationException(e);
    } catch (javax.naming.NoPermissionException e) {
      throw new AuthorizationException(e);
    } catch (NamingException e) {
      // Just treat it as a communication problem.
      throw new CommunicationException(e);
    }
  }
  // Creates a new managed object. The parent LDAP entry is assumed to
  // already exist.
  private <N extends ConfigurationClient> ManagedObject<N> createManagedObject(
      ManagedObjectPath path, ManagedObjectDefinition<N, ?> d,
      PropertySet properties) throws OperationsException {
    LdapName dn = LDAPNameBuilder.create(path);
    Attributes attributes = new BasicAttributes();
      PropertySet properties) throws ManagedObjectAlreadyExistsException,
      OperationRejectedException, AuthorizationException,
      CommunicationException {
    LdapName dn = LDAPNameBuilder.create(path, context.getLDAPProfile());
    Attributes attributes = new BasicAttributes(true);
    // Create the child's object class attribute.
    Attribute oc = new BasicAttribute("objectClass");
    for (String objectClass : profile.getObjectClasses(d)) {
    Attribute oc = new BasicAttribute("objectclass");
    for (String objectClass : context.getLDAPProfile().getObjectClasses(d)) {
      oc.add(objectClass);
    }
    attributes.put(oc);
@@ -698,7 +734,7 @@
    // Create the remaining attributes.
    for (PropertyDefinition<?> pd : d.getAllPropertyDefinitions()) {
      String attrID = profile.getAttributeName(d, pd);
      String attrID = context.getLDAPProfile().getAttributeName(d, pd);
      Attribute attribute = new BasicAttribute(attrID);
      encodeProperty(attribute, pd, properties);
      if (attribute.size() != 0) {
@@ -708,37 +744,17 @@
    try {
      // Create the entry.
      dirContext.createSubcontext(dn, attributes);
      context.getLDAPConnection().createEntry(dn, attributes);
    } catch (NameAlreadyBoundException e) {
      throw new ManagedObjectAlreadyExistsException();
    } catch (OperationNotSupportedException e) {
      // Unwilling to perform.
      throw new OperationRejectedException(e);
    } catch (NamingException e) {
      OperationsExceptionFactory oef = new OperationsExceptionFactory();
      throw oef.createException(e);
      adaptNamingException(e);
    }
    return new LDAPManagedObject<N>(dirContext, d, path, properties);
  }
  // Recursively delete a subtree of entries.
  private void destroySubtree(LdapName dn) throws NamingException {
    // List the child entries.
    String filter = "(objectClass=*)";
    SearchControls controls = new SearchControls();
    controls.setSearchScope(SearchControls.ONELEVEL_SCOPE);
    NamingEnumeration<SearchResult> results;
    results = dirContext.search(dn, filter, controls);
    // Recursively delete child entries.
    while (results.hasMore()) {
      SearchResult sr = results.next();
      LdapName child = new LdapName(dn.getRdns());
      child.add(new Rdn(sr.getName()));
      destroySubtree(child);
    }
    // Delete the specified entry.
    dirContext.destroySubcontext(dn);
    return new LDAPManagedObject<N>(context, d, path, properties);
  }
@@ -746,32 +762,35 @@
  // Encode a property into LDAP string values.
  private <T> void encodeProperty(Attribute attribute,
      PropertyDefinition<T> pd, PropertySet properties) {
    for (T value : properties.getPropertyValues(pd)) {
    Property<T> p = properties.getProperty(pd);
    for (T value : p.getPendingValues()) {
      attribute.add(pd.encodeValue(value));
    }
  }
  // Determine whether the named entry exists or not.
  private boolean entryExists(LdapName dn) throws NamingException {
    String filter = "(objectClass=*)";
    SearchControls controls = new SearchControls();
    controls.setSearchScope(SearchControls.OBJECT_SCOPE);
    try {
      NamingEnumeration<SearchResult> results = dirContext.search(dn,
          filter, controls);
      if (results.hasMore()) {
        // TODO: should really verify that the relation entry has
        // the correct object classes, etc. It definitely has the
        // correct name, which is ok.
        return true;
      }
    } catch (NameNotFoundException e) {
      // Fall through - parent not found.
  // Makes sure that the entry corresponding to this managed object
  // exists.
  private void ensureThisManagedObjectExists()
      throws ConcurrentModificationException, CommunicationException,
      AuthorizationException {
    LdapName dn = LDAPNameBuilder.create(path, context.getLDAPProfile());
    if (!entryExists(dn)) {
      throw new ConcurrentModificationException();
    }
  }
  // Determine whether the named entry exists or not.
  private boolean entryExists(LdapName dn) throws CommunicationException,
      AuthorizationException {
    try {
      return context.getLDAPConnection().entryExists(dn);
    } catch (NamingException e) {
      adaptNamingException(e);
    }
    return false;
  }
@@ -779,16 +798,19 @@
  // Remove the named managed object.
  private void removeManagedObject(ManagedObjectPath p)
      throws OperationsException {
    try {
      LdapName dn = LDAPNameBuilder.create(p);
      if (entryExists(dn)) {
        // Delete the entry and any subordinate entries.
        destroySubtree(dn);
      throws CommunicationException, AuthorizationException,
      OperationRejectedException {
    LdapName dn = LDAPNameBuilder.create(p, context.getLDAPProfile());
    if (entryExists(dn)) {
      // Delete the entry and any subordinate entries.
      try {
        context.getLDAPConnection().deleteSubtree(dn);
      } catch (OperationNotSupportedException e) {
        // Unwilling to perform.
        throw new OperationRejectedException(e);
      } catch (NamingException e) {
        adaptNamingException(e);
      }
    } catch (NamingException e) {
      OperationsExceptionFactory oef = new OperationsExceptionFactory();
      throw oef.createException(e);
    }
  }
@@ -801,8 +823,8 @@
    ManagedObjectDefinition d = getManagedObjectDefinition();
    RelationDefinition tmp = d.getRelationDefinition(rd.getName());
    if (tmp != rd) {
      throw new IllegalArgumentException("The relation "
          + rd.getName() + " is not associated with a " + d.getName());
      throw new IllegalArgumentException("The relation " + rd.getName()
          + " is not associated with a " + d.getName());
    }
  }
}
opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagementContext.java
@@ -29,16 +29,11 @@
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import javax.naming.ldap.InitialLdapContext;
import org.opends.server.admin.LDAPProfile;
import org.opends.server.admin.client.ManagedObject;
import org.opends.server.admin.client.ManagementContext;
import org.opends.server.admin.std.client.RootCfgClient;
import org.opends.server.util.Validator;
@@ -47,47 +42,56 @@
 */
public final class LDAPManagementContext extends ManagementContext {
  // The JNDI context used for the ldap connection.
  private final DirContext dirContext;
  /**
   * Create a new LDAP management context using simple authentication.
   * <p>
   * TODO: we will want to support more secure forms of
   * authentication.
   * Create a new LDAP management context using the provided LDAP
   * connection.
   *
   * @param host
   *          The host.
   * @param port
   *          The port.
   * @param name
   *          The LDAP bind DN.
   * @param password
   *          The LDAP bind password.
   * @param connection
   *          The LDAP connectin.
   * @return Returns the new management context.
   * @throws NamingException
   *           If the LDAP connection could not be established.
   */
  public static ManagementContext createLDAPContext(String host,
      int port, String name, String password) throws NamingException {
    Hashtable<String, Object> env = new Hashtable<String, Object>();
    env.put(Context.INITIAL_CONTEXT_FACTORY,
        "com.sun.jndi.ldap.LdapCtxFactory");
    env.put(Context.PROVIDER_URL, "ldap://" + host + ":" + port);
    env.put(Context.SECURITY_PRINCIPAL, name);
    env.put(Context.SECURITY_CREDENTIALS, password);
    DirContext ctx = new InitialLdapContext(env, null);
    return new LDAPManagementContext(ctx);
  public static ManagementContext createFromContext(LDAPConnection connection) {
    Validator.ensureNotNull(connection);
    return new LDAPManagementContext(connection, LDAPProfile.getInstance());
  }
  /**
   * Create a new LDAP management context using the provided LDAP
   * connection and LDAP profile.
   * <p>
   * This constructor is primarily intended for testing purposes so
   * that unit tests can provide mock LDAP connections and LDAP
   * profiles.
   *
   * @param connection
   *          The LDAP connection.
   * @param profile
   *          The LDAP profile which should be used to construct LDAP
   *          requests and decode LDAP responses.
   * @return Returns the new management context.
   */
  public static ManagementContext createFromContext(LDAPConnection connection,
      LDAPProfile profile) {
    Validator.ensureNotNull(connection, profile);
    return new LDAPManagementContext(connection, profile);
  }
  // The LDAP connection.
  private final LDAPConnection connection;
  // The LDAP profile which should be used to construct LDAP requests
  // and decode LDAP responses.
  private final LDAPProfile profile;
  // Private constructor.
  private LDAPManagementContext(DirContext dirContext) {
    this.dirContext = dirContext;
  private LDAPManagementContext(LDAPConnection connection,
      LDAPProfile profile) {
    this.connection = connection;
    this.profile = profile;
  }
@@ -96,6 +100,31 @@
   * {@inheritDoc}
   */
  public ManagedObject<RootCfgClient> getRootConfigurationManagedObject() {
    return LDAPManagedObject.getRootManagedObject(dirContext);
    return LDAPManagedObject.getRootManagedObject(this);
  }
  /**
   * Gets the LDAP connection used for interacting with the server.
   *
   * @return Returns the LDAP connection used for interacting with the
   *         server.
   */
  LDAPConnection getLDAPConnection() {
    return connection;
  }
  /**
   * Gets the LDAP profile which should be used to construct LDAP
   * requests and decode LDAP responses.
   *
   * @return Returns the LDAP profile which should be used to
   *         construct LDAP requests and decode LDAP responses.
   */
  LDAPProfile getLDAPProfile() {
    return profile;
  }
}
opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPNameBuilder.java
@@ -54,15 +54,19 @@
final class LDAPNameBuilder implements ManagedObjectPathSerializer {
  /**
   * Creates a new LDAP name representing the specified managed object path.
   * Creates a new LDAP name representing the specified managed object
   * path.
   *
   * @param path
   *          The managed object path.
   * @return Returns a new LDAP name representing the specified managed object
   *         path.
   * @param profile
   *          The LDAP profile which should be used to construct LDAP
   *          names.
   * @return Returns a new LDAP name representing the specified
   *         managed object path.
   */
  public static LdapName create(ManagedObjectPath path) {
    LDAPNameBuilder builder = new LDAPNameBuilder();
  public static LdapName create(ManagedObjectPath path, LDAPProfile profile) {
    LDAPNameBuilder builder = new LDAPNameBuilder(profile);
    path.serialize(builder);
    return builder.getInstance();
  }
@@ -70,19 +74,22 @@
  /**
   * Creates a new LDAP name representing the specified managed object path and
   * instantiable relation.
   * Creates a new LDAP name representing the specified managed object
   * path and instantiable relation.
   *
   * @param path
   *          The managed object path.
   * @param relation
   *          The child instantiable relation.
   * @return Returns a new LDAP name representing the specified managed object
   *         path and instantiable relation.
   * @param profile
   *          The LDAP profile which should be used to construct LDAP
   *          names.
   * @return Returns a new LDAP name representing the specified
   *         managed object path and instantiable relation.
   */
  public static LdapName create(ManagedObjectPath path,
      InstantiableRelationDefinition<?, ?> relation) {
    LDAPNameBuilder builder = new LDAPNameBuilder();
      InstantiableRelationDefinition<?, ?> relation, LDAPProfile profile) {
    LDAPNameBuilder builder = new LDAPNameBuilder(profile);
    path.serialize(builder);
    builder.appendManagedObjectPathElement(relation);
    return builder.getInstance();
@@ -98,10 +105,14 @@
  /**
   * Create a new JNDI LDAP name builder.
   *
   * @param profile
   *          The LDAP profile which should be used to construct LDAP
   *          names.
   */
  public LDAPNameBuilder() {
  public LDAPNameBuilder(LDAPProfile profile) {
    this.rdns = new LinkedList<Rdn>();
    this.profile = LDAPProfile.getInstance();
    this.profile = profile;
  }
opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/OperationsExceptionFactory.java
File was deleted
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/DurationPropertyDefinitionTest.java
@@ -317,7 +317,7 @@
    builder.setAllowUnlimited(true);
    DurationPropertyDefinition spd = buildTestDefinition(builder);
    PropertyDefinitionVisitor<Boolean, Void> v = new AbstractPropertyDefinitionVisitor<Boolean, Void>() {
    PropertyDefinitionVisitor<Boolean, Void> v = new PropertyDefinitionVisitor<Boolean, Void>() {
      public Boolean visitDuration(DurationPropertyDefinition d,
          Void o) {
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/IntegerPropertyDefinitionTest.java
@@ -271,7 +271,7 @@
    IntegerPropertyDefinition.Builder builder = createTestBuilder();
    builder.setAllowUnlimited(true);
    IntegerPropertyDefinition spd = buildTestDefinition(builder);
    PropertyDefinitionVisitor<Boolean, Void> v = new AbstractPropertyDefinitionVisitor<Boolean, Void>() {
    PropertyDefinitionVisitor<Boolean, Void> v = new PropertyDefinitionVisitor<Boolean, Void>() {
      public Boolean visitInteger(IntegerPropertyDefinition d,
          Void o) {
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/MockLDAPProfile.java
File was renamed from opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/MockLDAPProfile.java
@@ -24,10 +24,12 @@
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.server.admin.server;
package org.opends.server.admin;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import org.opends.server.admin.AbstractManagedObjectDefinition;
@@ -68,17 +70,6 @@
   * {@inheritDoc}
   */
  @Override
  public String getFilter(AbstractManagedObjectDefinition<?, ?> d) {
    // Not implemented yet.
    throw new UnsupportedOperationException();
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public String getInstantiableRelationChildRDNType(
      InstantiableRelationDefinition<?, ?> r) {
    return "cn";
@@ -92,8 +83,7 @@
  @Override
  public List<String> getInstantiableRelationObjectClasses(
      InstantiableRelationDefinition<?, ?> r) {
    // Not implemented yet.
    throw new UnsupportedOperationException();
    return Arrays.asList(new String[] { "top", "ds-cfg-branch" });
  }
@@ -103,8 +93,7 @@
   */
  @Override
  public String getObjectClass(AbstractManagedObjectDefinition<?, ?> d) {
    // Not implemented yet.
    throw new UnsupportedOperationException();
    return "ds-cfg-" + d.getName();
  }
@@ -113,10 +102,16 @@
   * {@inheritDoc}
   */
  @Override
  public List<String> getObjectClasses(
      AbstractManagedObjectDefinition<?, ?> d) {
    // Not implemented yet.
    throw new UnsupportedOperationException();
  public List<String> getObjectClasses(AbstractManagedObjectDefinition<?, ?> d) {
    LinkedList<String> objectClasses = new LinkedList<String>();
    for (AbstractManagedObjectDefinition<?, ?> i = d; i != null; i = i
        .getParent()) {
      objectClasses.addFirst(getObjectClass(i));
    }
    // Make sure that we have top.
    objectClasses.addFirst("top");
    return objectClasses;
  }
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/SizePropertyDefinitionTest.java
@@ -285,7 +285,7 @@
    SizePropertyDefinition.Builder builder = createTestBuilder();
    builder.setAllowUnlimited(true);
    SizePropertyDefinition spd = buildTestDefinition(builder);
    PropertyDefinitionVisitor<Boolean, Void> v = new AbstractPropertyDefinitionVisitor<Boolean, Void>() {
    PropertyDefinitionVisitor<Boolean, Void> v = new PropertyDefinitionVisitor<Boolean, Void>() {
      public Boolean visitSize(SizePropertyDefinition d,
          Void o) {
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestChildCfg.java
File was renamed from opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/TestChildCfg.java
@@ -24,7 +24,7 @@
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.server.admin.server;
package org.opends.server.admin;
@@ -43,4 +43,12 @@
   */
  ManagedObjectDefinition<? extends TestChildCfgClient, ? extends TestChildCfg> definition();
  /**
   * Get the "heartbeat-interval" property.
   *
   * @return Returns the value of the "heartbeat-interval" property.
   */
  long getHeartbeatInterval();
}
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestChildCfgClient.java
File was renamed from opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/TestChildCfgClient.java
@@ -24,7 +24,7 @@
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.server.admin.server;
package org.opends.server.admin;
@@ -43,4 +43,24 @@
   */
  ManagedObjectDefinition<? extends TestChildCfgClient, ? extends TestChildCfg> definition();
  /**
   * Get the "heartbeat-interval" property.
   *
   * @return Returns the value of the "heartbeat-interval" property.
   */
  long getHeartbeatInterval();
  /**
   * Set the "heartbeat-interval" property.
   *
   * @param value
   *          The value of the "heartbeat-interval" property.
   * @throws IllegalPropertyValueException
   *           If the new value is invalid.
   */
  void setHeartbeatInterval(Long value) throws IllegalPropertyValueException;
}
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestChildCfgDefn.java
New file
@@ -0,0 +1,251 @@
/*
 * 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/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * 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/opends/resource/legal-notices/OpenDS.LICENSE.  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
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.server.admin;
import org.opends.server.admin.client.AuthorizationException;
import org.opends.server.admin.client.CommunicationException;
import org.opends.server.admin.client.ConcurrentModificationException;
import org.opends.server.admin.client.ManagedObject;
import org.opends.server.admin.client.OperationRejectedException;
import org.opends.server.admin.server.ServerManagedObject;
import org.opends.server.types.DN;
/**
 * A sample configuration definition class for testing.
 */
public final class TestChildCfgDefn extends
    ManagedObjectDefinition<TestChildCfgClient, TestChildCfg> {
  // The singleton configuration definition instance.
  private static final TestChildCfgDefn INSTANCE = new TestChildCfgDefn();
  // The "heartbeat-interval" property definition.
  private static final DurationPropertyDefinition PD_HEARTBEAT_INTERVAL;
  // Build the "heartbeat-interval" property definition.
  static {
    DurationPropertyDefinition.Builder builder = DurationPropertyDefinition
        .createBuilder(INSTANCE, "heartbeat-interval");
    DefaultBehaviorProvider<Long> provider = new DefinedDefaultBehaviorProvider<Long>(
        "1000ms");
    builder.setDefaultBehaviorProvider(provider);
    builder.setAllowUnlimited(false);
    builder.setBaseUnit("ms");
    builder.setLowerLimit("100");
    PD_HEARTBEAT_INTERVAL = builder.getInstance();
    INSTANCE.registerPropertyDefinition(PD_HEARTBEAT_INTERVAL);
  }
  /**
   * Get the definition singleton.
   *
   * @return Returns the definition singleton.
   */
  public static TestChildCfgDefn getInstance() {
    return INSTANCE;
  }
  /**
   * Private constructor.
   */
  private TestChildCfgDefn() {
    super("test-child", null);
  }
  /**
   * {@inheritDoc}
   */
  public TestChildCfgClient createClientConfiguration(
      ManagedObject<? extends TestChildCfgClient> impl) {
    return new TestChildCfgClientImpl(impl);
  }
  /**
   * {@inheritDoc}
   */
  public TestChildCfg createServerConfiguration(
      ServerManagedObject<? extends TestChildCfg> impl) {
    return new TestChildCfgServerImpl(impl);
  }
  /**
   * {@inheritDoc}
   */
  public Class<TestChildCfg> getServerConfigurationClass() {
    return TestChildCfg.class;
  }
  /**
   * Get the "heartbeat-interval" property definition.
   *
   * @return Returns the "heartbeat-interval" property definition.
   */
  public DurationPropertyDefinition getHeartbeatIntervalPropertyDefinition() {
    return PD_HEARTBEAT_INTERVAL;
  }
  /**
   * Managed object client implementation.
   */
  private static class TestChildCfgClientImpl implements TestChildCfgClient {
    // Private implementation.
    private ManagedObject<? extends TestChildCfgClient> impl;
    // Private constructor.
    private TestChildCfgClientImpl(
        ManagedObject<? extends TestChildCfgClient> impl) {
      this.impl = impl;
    }
    /**
     * {@inheritDoc}
     */
    public long getHeartbeatInterval() {
      return impl.getPropertyValue(INSTANCE
          .getHeartbeatIntervalPropertyDefinition());
    }
    /**
     * {@inheritDoc}
     */
    public void setHeartbeatInterval(Long value) {
      impl.setPropertyValue(INSTANCE.getHeartbeatIntervalPropertyDefinition(),
          value);
    }
    /**
     * {@inheritDoc}
     */
    public ManagedObjectDefinition<? extends TestChildCfgClient, ? extends TestChildCfg> definition() {
      return INSTANCE;
    }
    /**
     * {@inheritDoc}
     */
    public PropertyProvider properties() {
      return impl;
    }
    /**
     * {@inheritDoc}
     */
    public void commit() throws ConcurrentModificationException,
        OperationRejectedException, AuthorizationException,
        CommunicationException {
      impl.commit();
    }
  }
  /**
   * Managed object server implementation.
   */
  private static class TestChildCfgServerImpl implements TestChildCfg {
    // Private implementation.
    private ServerManagedObject<? extends TestChildCfg> impl;
    // Private constructor.
    private TestChildCfgServerImpl(
        ServerManagedObject<? extends TestChildCfg> impl) {
      this.impl = impl;
    }
    /**
     * {@inheritDoc}
     */
    public long getHeartbeatInterval() {
      return impl.getPropertyValue(INSTANCE
          .getHeartbeatIntervalPropertyDefinition());
    }
    /**
     * {@inheritDoc}
     */
    public ManagedObjectDefinition<? extends TestChildCfgClient, ? extends TestChildCfg> definition() {
      return INSTANCE;
    }
    /**
     * {@inheritDoc}
     */
    public PropertyProvider properties() {
      return impl;
    }
    /**
     * {@inheritDoc}
     */
    public DN dn() {
      return impl.getDN();
    }
  }
}
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestParentCfg.java
File was renamed from opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/TestParentCfg.java
@@ -24,12 +24,10 @@
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.server.admin.server;
package org.opends.server.admin;
import org.opends.server.admin.Configuration;
import org.opends.server.admin.ManagedObjectDefinition;
@@ -43,4 +41,21 @@
   */
  ManagedObjectDefinition<? extends TestParentCfgClient, ? extends TestParentCfg> definition();
  /**
   * Get the "maximum-length" property.
   *
   * @return Returns the value of the "maximum-length" property.
   */
  int getMaximumLength();
  /**
   * Get the "minimum-length" property.
   *
   * @return Returns the value of the "minimum-length" property.
   */
  int getMinimumLength();
}
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestParentCfgClient.java
New file
@@ -0,0 +1,214 @@
/*
 * 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/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * 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/opends/resource/legal-notices/OpenDS.LICENSE.  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
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.server.admin;
import org.opends.server.admin.ConfigurationClient;
import org.opends.server.admin.ManagedObjectDefinition;
import org.opends.server.admin.client.AuthorizationException;
import org.opends.server.admin.client.CommunicationException;
import org.opends.server.admin.client.ConcurrentModificationException;
import org.opends.server.admin.client.ManagedObjectDecodingException;
import org.opends.server.admin.client.OperationRejectedException;
/**
 * A sample client-side configuration interface for testing.
 */
public interface TestParentCfgClient extends ConfigurationClient {
  /**
   * {@inheritDoc}
   */
  ManagedObjectDefinition<? extends TestParentCfgClient, ? extends TestParentCfg> definition();
  /**
   * Lists the test children.
   *
   * @return Returns an array containing the names of the test
   *         children.
   * @throws ConcurrentModificationException
   *           If this test parent has been removed from the server by
   *           another client.
   * @throws AuthorizationException
   *           If the server refuses to list the test children because
   *           the client does not have the correct privileges.
   * @throws CommunicationException
   *           If the client cannot contact the server due to an
   *           underlying communication problem.
   */
  String[] listTestChildren() throws ConcurrentModificationException,
      AuthorizationException, CommunicationException;
  /**
   * Gets the named test child.
   *
   * @param name
   *          The name of the test child to retrieve.
   * @return Returns the named test child.
   * @throws DefinitionDecodingException
   *           If the named test child was found but its type could
   *           not be determined.
   * @throws ManagedObjectDecodingException
   *           If the named test child was found but one or more of
   *           its properties could not be decoded.
   * @throws ManagedObjectNotFoundException
   *           If the named test child was not found on the server.
   * @throws ConcurrentModificationException
   *           If this test parent has been removed from the server by
   *           another client.
   * @throws AuthorizationException
   *           If the server refuses to retrieve the named test child
   *           because the client does not have the correct
   *           privileges.
   * @throws CommunicationException
   *           If the client cannot contact the server due to an
   *           underlying communication problem.
   */
  TestChildCfgClient getTestChild(String name)
      throws DefinitionDecodingException, ManagedObjectDecodingException,
      ManagedObjectNotFoundException, ConcurrentModificationException,
      AuthorizationException, CommunicationException;
  /**
   * Creates a new test child.
   *
   * @param <C>
   *          The type of the test child being added.
   * @param d
   *          The definition of the test child to be created.
   * @param name
   *          The name of the new test child.
   * @param p
   *          A property provider which can be used to initialize the
   *          property values of the new test child.
   * @return Returns a new test child instance representing the test
   *         child that was created.
   * @throws ManagedObjectDecodingException
   *           If the test child could not be created because one or
   *           more of its properties are invalid.
   * @throws ManagedObjectAlreadyExistsException
   *           If the test child cannot be created because it already
   *           exists on the server.
   * @throws ConcurrentModificationException
   *           If this test parent has been removed from the server by
   *           another client.
   * @throws OperationRejectedException
   *           If the server refuses to create the test child due to
   *           some server-side constraint which cannot be satisfied.
   * @throws AuthorizationException
   *           If the server refuses to create the test child because
   *           the client does not have the correct privileges.
   * @throws CommunicationException
   *           If the client cannot contact the server due to an
   *           underlying communication problem.
   */
  <C extends TestChildCfgClient> C createTestChild(
      ManagedObjectDefinition<C, ?> d, String name, PropertyProvider p)
      throws ManagedObjectDecodingException,
      ManagedObjectAlreadyExistsException, ConcurrentModificationException,
      OperationRejectedException, AuthorizationException,
      CommunicationException;
  /**
   * Removes the named test child.
   *
   * @param name
   *          The name of the test child to remove.
   * @throws ManagedObjectNotFoundException
   *           If the test child does not exist.
   * @throws OperationRejectedException
   *           If the server refuses to remove the test child due to
   *           some server-side constraint which cannot be satisfied
   *           (for example, if it is referenced by another managed
   *           object).
   * @throws ConcurrentModificationException
   *           If this test parent has been removed from the server by
   *           another client.
   * @throws AuthorizationException
   *           If the server refuses to remove the test child because
   *           the client does not have the correct privileges.
   * @throws CommunicationException
   *           If the client cannot contact the server due to an
   *           underlying communication problem.
   */
  void removeTestChild(String name) throws ManagedObjectNotFoundException,
      OperationRejectedException, ConcurrentModificationException,
      AuthorizationException, CommunicationException;
  /**
   * Get the "maximum-length" property.
   *
   * @return Returns the value of the "maximum-length" property.
   */
  int getMaximumLength();
  /**
   * Set the "maximum-length" property.
   *
   * @param value
   *          The value of the "maximum-length" property.
   * @throws IllegalPropertyValueException
   *           If the new value is invalid.
   */
  void setMaximumLength(Integer value) throws IllegalPropertyValueException;
  /**
   * Get the "minimum-length" property.
   *
   * @return Returns the value of the "minimum-length" property.
   */
  int getMinimumLength();
  /**
   * Set the "minimum-length" property.
   *
   * @param value
   *          The value of the "minimum-length" property.
   * @throws IllegalPropertyValueException
   *           If the new value is invalid.
   */
  void setMinimumLength(Integer value) throws IllegalPropertyValueException;
}
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestParentCfgDefn.java
New file
@@ -0,0 +1,391 @@
/*
 * 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/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * 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/opends/resource/legal-notices/OpenDS.LICENSE.  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
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.server.admin;
import org.opends.server.admin.client.AuthorizationException;
import org.opends.server.admin.client.CommunicationException;
import org.opends.server.admin.client.ConcurrentModificationException;
import org.opends.server.admin.client.ManagedObject;
import org.opends.server.admin.client.ManagedObjectDecodingException;
import org.opends.server.admin.client.OperationRejectedException;
import org.opends.server.admin.server.ServerManagedObject;
import org.opends.server.admin.std.meta.RootCfgDefn;
import org.opends.server.types.DN;
/**
 * A sample configuration definition class for testing.
 */
public final class TestParentCfgDefn extends
    ManagedObjectDefinition<TestParentCfgClient, TestParentCfg> {
  // The singleton configuration definition instance.
  private static final TestParentCfgDefn INSTANCE = new TestParentCfgDefn();
  /**
   * The relation between this definition and the root.
   */
  public static final InstantiableRelationDefinition<TestParentCfgClient, TestParentCfg> RD_TEST_PARENT;
  // The "test-children" relation definition.
  private static final InstantiableRelationDefinition<TestChildCfgClient, TestChildCfg> RD_TEST_CHILDREN;
  // The "maximum-length" property definition.
  private static final IntegerPropertyDefinition PD_MAXIMUM_LENGTH;
  // The "minimum-length" property definition.
  private static final IntegerPropertyDefinition PD_MINIMUM_LENGTH;
  // Build the "maximum-length" property definition.
  static {
    IntegerPropertyDefinition.Builder builder = IntegerPropertyDefinition
        .createBuilder(INSTANCE, "maximum-length");
    DefaultBehaviorProvider<Integer> provider = new DefinedDefaultBehaviorProvider<Integer>(
        "456");
    builder.setDefaultBehaviorProvider(provider);
    builder.setLowerLimit(0);
    PD_MAXIMUM_LENGTH = builder.getInstance();
    INSTANCE.registerPropertyDefinition(PD_MAXIMUM_LENGTH);
  }
  // Build the "minimum-length" property definition.
  static {
    IntegerPropertyDefinition.Builder builder = IntegerPropertyDefinition
        .createBuilder(INSTANCE, "minimum-length");
    DefaultBehaviorProvider<Integer> provider = new DefinedDefaultBehaviorProvider<Integer>(
        "123");
    builder.setDefaultBehaviorProvider(provider);
    builder.setLowerLimit(0);
    PD_MINIMUM_LENGTH = builder.getInstance();
    INSTANCE.registerPropertyDefinition(PD_MINIMUM_LENGTH);
  }
  // Register this as a relation against the root configuration.
  static {
    RD_TEST_PARENT = new InstantiableRelationDefinition<TestParentCfgClient, TestParentCfg>(
        INSTANCE, "test-parent", "test-parents", INSTANCE);
    RootCfgDefn.getInstance().registerRelationDefinition(RD_TEST_PARENT);
  }
  // Build the "test-children" relation definition.
  static {
    RD_TEST_CHILDREN = new InstantiableRelationDefinition<TestChildCfgClient, TestChildCfg>(
        INSTANCE, "test-child", "test-children", TestChildCfgDefn.getInstance());
    INSTANCE.registerRelationDefinition(RD_TEST_CHILDREN);
  }
  /**
   * Get the definition singleton.
   *
   * @return Returns the definition singleton.
   */
  public static TestParentCfgDefn getInstance() {
    return INSTANCE;
  }
  /**
   * Private constructor.
   */
  private TestParentCfgDefn() {
    super("test-parent", null);
  }
  /**
   * Get the "maximum-length" property definition.
   *
   * @return Returns the "maximum-length" property definition.
   */
  public IntegerPropertyDefinition getMaximumLengthPropertyDefinition() {
    return PD_MAXIMUM_LENGTH;
  }
  /**
   * Get the "minimum-length" property definition.
   *
   * @return Returns the "minimum-length" property definition.
   */
  public IntegerPropertyDefinition getMinimumLengthPropertyDefinition() {
    return PD_MINIMUM_LENGTH;
  }
  /**
   * Get the "test-children" relation definition.
   *
   * @return Returns the "test-children" relation definition.
   */
  public InstantiableRelationDefinition<TestChildCfgClient, TestChildCfg> getTestChildrenRelationDefinition() {
    return RD_TEST_CHILDREN;
  }
  /**
   * {@inheritDoc}
   */
  public TestParentCfgClient createClientConfiguration(
      ManagedObject<? extends TestParentCfgClient> impl) {
    return new TestParentCfgClientImpl(impl);
  }
  /**
   * {@inheritDoc}
   */
  public TestParentCfg createServerConfiguration(
      ServerManagedObject<? extends TestParentCfg> impl) {
    return new TestParentCfgServerImpl(impl);
  }
  /**
   * {@inheritDoc}
   */
  public Class<TestParentCfg> getServerConfigurationClass() {
    return TestParentCfg.class;
  }
  /**
   * Managed object client implementation.
   */
  private static class TestParentCfgClientImpl implements TestParentCfgClient {
    // Private implementation.
    private ManagedObject<? extends TestParentCfgClient> impl;
    // Private constructor.
    private TestParentCfgClientImpl(
        ManagedObject<? extends TestParentCfgClient> impl) {
      this.impl = impl;
    }
    /**
     * {@inheritDoc}
     */
    public int getMaximumLength() {
      return impl.getPropertyValue(INSTANCE
          .getMaximumLengthPropertyDefinition());
    }
    /**
     * {@inheritDoc}
     */
    public void setMaximumLength(Integer value) {
      impl.setPropertyValue(INSTANCE.getMaximumLengthPropertyDefinition(),
          value);
    }
    /**
     * {@inheritDoc}
     */
    public int getMinimumLength() {
      return impl.getPropertyValue(INSTANCE
          .getMinimumLengthPropertyDefinition());
    }
    /**
     * {@inheritDoc}
     */
    public void setMinimumLength(Integer value) {
      impl.setPropertyValue(INSTANCE.getMinimumLengthPropertyDefinition(),
          value);
    }
    /**
     * {@inheritDoc}
     */
    public ManagedObjectDefinition<? extends TestParentCfgClient, ? extends TestParentCfg> definition() {
      return INSTANCE;
    }
    /**
     * {@inheritDoc}
     */
    public PropertyProvider properties() {
      return impl;
    }
    /**
     * {@inheritDoc}
     */
    public void commit() throws ConcurrentModificationException,
        OperationRejectedException, AuthorizationException,
        CommunicationException {
      impl.commit();
    }
    /**
     * {@inheritDoc}
     */
    public <C extends TestChildCfgClient> C createTestChild(
        ManagedObjectDefinition<C, ?> d, String name, PropertyProvider p)
        throws ManagedObjectDecodingException,
        ManagedObjectAlreadyExistsException, ConcurrentModificationException,
        OperationRejectedException, AuthorizationException,
        CommunicationException {
      return impl.createChild(INSTANCE.getTestChildrenRelationDefinition(), d,
          name, p).getConfiguration();
    }
    /**
     * {@inheritDoc}
     */
    public TestChildCfgClient getTestChild(String name)
        throws DefinitionDecodingException, ManagedObjectDecodingException,
        ManagedObjectNotFoundException, ConcurrentModificationException,
        AuthorizationException, CommunicationException {
      return impl.getChild(INSTANCE.getTestChildrenRelationDefinition(), name)
          .getConfiguration();
    }
    /**
     * {@inheritDoc}
     */
    public String[] listTestChildren() throws ConcurrentModificationException,
        AuthorizationException, CommunicationException {
      return impl.listChildren(INSTANCE.getTestChildrenRelationDefinition());
    }
    /**
     * {@inheritDoc}
     */
    public void removeTestChild(String name)
        throws ManagedObjectNotFoundException, OperationRejectedException,
        ConcurrentModificationException, AuthorizationException,
        CommunicationException {
      impl.removeChild(INSTANCE.getTestChildrenRelationDefinition(), name);
    }
  }
  /**
   * Managed object server implementation.
   */
  private static class TestParentCfgServerImpl implements TestParentCfg {
    // Private implementation.
    private ServerManagedObject<? extends TestParentCfg> impl;
    // Private constructor.
    private TestParentCfgServerImpl(
        ServerManagedObject<? extends TestParentCfg> impl) {
      this.impl = impl;
    }
    /**
     * {@inheritDoc}
     */
    public int getMaximumLength() {
      return impl.getPropertyValue(INSTANCE
          .getMaximumLengthPropertyDefinition());
    }
    /**
     * {@inheritDoc}
     */
    public int getMinimumLength() {
      return impl.getPropertyValue(INSTANCE
          .getMinimumLengthPropertyDefinition());
    }
    /**
     * {@inheritDoc}
     */
    public ManagedObjectDefinition<? extends TestParentCfgClient, ? extends TestParentCfg> definition() {
      return INSTANCE;
    }
    /**
     * {@inheritDoc}
     */
    public PropertyProvider properties() {
      return impl;
    }
    /**
     * {@inheritDoc}
     */
    public DN dn() {
      return impl.getDN();
    }
  }
}
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/CreateEntryMockLDAPConnection.java
New file
@@ -0,0 +1,137 @@
/*
 * 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/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * 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/opends/resource/legal-notices/OpenDS.LICENSE.  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
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.server.admin.client.ldap;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.naming.InvalidNameException;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.ldap.LdapName;
import org.opends.server.util.Validator;
import org.testng.Assert;
/**
 * A mock LDAP connection which is used to verify that an add
 * operation was requested and that it has the correct parameters.
 */
public final class CreateEntryMockLDAPConnection extends MockLDAPConnection {
  // Detect multiple calls.
  private boolean alreadyAdded = false;
  // The expected set of attributes (attribute name -> list of
  // values).
  private final Map<String, List<String>> attributes = new HashMap<String, List<String>>();
  // The expected DN.
  private final LdapName expectedDN;
  /**
   * Create a new mock ldap connection for detecting add operations.
   *
   * @param dn
   *          The expected DN of the entry to be added.
   */
  public CreateEntryMockLDAPConnection(String dn) {
    try {
      this.expectedDN = new LdapName(dn);
    } catch (InvalidNameException e) {
      throw new RuntimeException(e);
    }
  }
  /**
   * Add an attribute which should be part of the add operation.
   *
   * @param expectedName
   *          The name of the expected attribute.
   * @param expectedValues
   *          The attribute's expected values (never empty).
   */
  public void addExpectedAttribute(String expectedName,
      String... expectedValues) {
    Validator.ensureNotNull(expectedName);
    Validator.ensureNotNull(expectedValues);
    Validator.ensureTrue(expectedValues.length > 0);
    attributes.put(expectedName, Arrays.asList(expectedValues));
  }
  /**
   * Asserts that the entry was created.
   */
  public void assertEntryIsCreated() {
    Assert.assertTrue(alreadyAdded);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public void createEntry(LdapName dn, Attributes attributes)
      throws NamingException {
    Assert.assertFalse(alreadyAdded);
    Assert.assertEquals(dn, expectedDN);
    Map<String, List<String>> expected = new HashMap<String, List<String>>(
        this.attributes);
    NamingEnumeration<? extends Attribute> ne = attributes.getAll();
    while (ne.hasMore()) {
      Attribute attribute = ne.next();
      String attrID = attribute.getID();
      List<String> values = expected.remove(attrID);
      if (values == null) {
        Assert.fail("Unexpected attribute " + attrID);
      }
      assertAttributeEquals(attribute, values);
    }
    if (!expected.isEmpty()) {
      Assert.fail("Missing expected attributes: " + expected.keySet());
    }
    alreadyAdded = true;
  }
}
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/DeleteSubtreeMockLDAPConnection.java
New file
@@ -0,0 +1,87 @@
/*
 * 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/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * 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/opends/resource/legal-notices/OpenDS.LICENSE.  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
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.server.admin.client.ldap;
import javax.naming.InvalidNameException;
import javax.naming.NamingException;
import javax.naming.ldap.LdapName;
import org.testng.Assert;
/**
 * A mock LDAP connection which is used to verify that a delete
 * subtree takes place.
 */
public final class DeleteSubtreeMockLDAPConnection extends MockLDAPConnection {
  // Detect multiple calls.
  private boolean alreadyDeleted = false;
  // The expected DN.
  private final LdapName expectedDN;
  /**
   * Create a new mock ldap connection for detecting subtree deletes.
   *
   * @param dn
   *          The expected subtree DN.
   */
  public DeleteSubtreeMockLDAPConnection(String dn) {
    try {
      this.expectedDN = new LdapName(dn);
    } catch (InvalidNameException e) {
      throw new RuntimeException(e);
    }
  }
  /**
   * Asserts that the subtree was deleted.
   */
  public void assertSubtreeIsDeleted() {
    Assert.assertTrue(alreadyDeleted);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public void deleteSubtree(LdapName dn) throws NamingException {
    Assert.assertFalse(alreadyDeleted);
    Assert.assertEquals(dn, expectedDN);
    alreadyDeleted = true;
  }
}
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/LDAPClientTest.java
New file
@@ -0,0 +1,625 @@
/*
 * 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/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * 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/opends/resource/legal-notices/OpenDS.LICENSE.  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
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.server.admin.client.ldap;
import java.util.Collection;
import javax.naming.NamingException;
import javax.naming.OperationNotSupportedException;
import javax.naming.directory.Attributes;
import javax.naming.ldap.LdapName;
import org.opends.server.TestCaseUtils;
import org.opends.server.admin.AdminTestCase;
import org.opends.server.admin.DefinitionDecodingException;
import org.opends.server.admin.ManagedObjectAlreadyExistsException;
import org.opends.server.admin.ManagedObjectNotFoundException;
import org.opends.server.admin.MockLDAPProfile;
import org.opends.server.admin.PropertyProvider;
import org.opends.server.admin.TestChildCfgClient;
import org.opends.server.admin.TestChildCfgDefn;
import org.opends.server.admin.TestParentCfgClient;
import org.opends.server.admin.TestParentCfgDefn;
import org.opends.server.admin.client.AuthorizationException;
import org.opends.server.admin.client.CommunicationException;
import org.opends.server.admin.client.ConcurrentModificationException;
import org.opends.server.admin.client.ManagedObject;
import org.opends.server.admin.client.ManagedObjectDecodingException;
import org.opends.server.admin.client.ManagementContext;
import org.opends.server.admin.client.OperationRejectedException;
import org.opends.server.admin.std.client.RootCfgClient;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
/**
 * Administration framework LDAP client unit tests.
 */
public final class LDAPClientTest extends AdminTestCase {
  // Test LDIF.
  private static final String[] TEST_LDIF = new String[] {
      "dn: cn=test-parents", "objectclass: top", "objectclass: ds-cfg-branch",
      "cn: test-parents", "", "dn: cn=test parent 1, cn=test-parents",
      "objectclass: top", "objectclass: ds-cfg-test-parent",
      "cn: test parent 1", "", "dn: cn=test parent 2,cn=test-parents",
      "objectclass: top", "objectclass: ds-cfg-test-parent",
      "cn: test parent 2", "ds-cfg-minimum-length: 10000",
      "ds-cfg-maximum-length: 20000", "",
      "dn:cn=test-children,cn=test parent 1,cn=test-parents",
      "objectclass: top", "objectclass: ds-cfg-branch", "cn: test-children",
      "",
      "dn: cn=test child 1,cn=test-children,cn=test parent 1,cn=test-parents",
      "objectclass: top", "objectclass: ds-cfg-test-child", "cn: test child 1",
      "",
      "dn: cn=test child 2,cn=test-children,cn=test parent 1,cn=test-parents",
      "objectclass: top", "objectclass: ds-cfg-test-child", "cn: test child 2",
      "ds-cfg-heartbeat-interval: 12345s", "" };
  /**
   * Provide valid naming exception to client API exception mappings.
   *
   * @return Returns valid naming exception to client API exception
   *         mappings.
   */
  @DataProvider(name = "createManagedObjectExceptions")
  public Object[][] createManagedObjectExceptions() {
    return new Object[][] {
        { new javax.naming.CommunicationException(),
            CommunicationException.class },
        { new javax.naming.ServiceUnavailableException(),
            CommunicationException.class },
        { new javax.naming.CannotProceedException(),
            CommunicationException.class },
        { new javax.naming.NameAlreadyBoundException(),
            ManagedObjectAlreadyExistsException.class },
        { new javax.naming.NoPermissionException(),
            AuthorizationException.class },
        { new OperationNotSupportedException(),
            OperationRejectedException.class } };
  }
  /**
   * Provide valid naming exception to client API exception mappings.
   *
   * @return Returns valid naming exception to client API exception
   *         mappings.
   */
  @DataProvider(name = "getManagedObjectExceptions")
  public Object[][] getManagedObjectExceptions() {
    return new Object[][] {
        { new javax.naming.CommunicationException(),
            CommunicationException.class },
        { new javax.naming.ServiceUnavailableException(),
            CommunicationException.class },
        { new javax.naming.CannotProceedException(),
            CommunicationException.class },
        { new javax.naming.NameNotFoundException(),
            ManagedObjectNotFoundException.class },
        { new javax.naming.NoPermissionException(),
            AuthorizationException.class },
        { new OperationNotSupportedException(), CommunicationException.class } };
  }
  /**
   * Sets up tests
   *
   * @throws Exception
   *           If the server could not be initialized.
   */
  @BeforeClass
  public void setUp() throws Exception {
    // This test suite depends on having the schema available, so
    // we'll start the server.
    TestCaseUtils.startServer();
  }
  /**
   * Tests creation of a child managed object.
   *
   * @throws Exception
   *           If an unexpected error occurred.
   */
  @Test
  public void testCreateChildManagedObject() throws Exception {
    MockPropertyProvider p = new MockPropertyProvider();
    CreateEntryMockLDAPConnection c = new CreateEntryMockLDAPConnection(
        "cn=test child 3,cn=test-children,cn=test parent 1,cn=test-parents");
    c.importLDIF(TEST_LDIF);
    c.addExpectedAttribute("cn", "test child 3");
    c.addExpectedAttribute("objectclass", "top", "ds-cfg-test-child");
    // LDAP encoding uses base unit.
    p.addProperty("heartbeat-interval", "10s");
    c.addExpectedAttribute("ds-cfg-heartbeat-interval", "10000ms");
    ManagementContext ctx = LDAPManagementContext.createFromContext(c,
        new MockLDAPProfile());
    TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
    parent.createTestChild(TestChildCfgDefn.getInstance(), "test child 3", p);
    c.assertEntryIsCreated();
  }
  /**
   * Tests creation of a child managed object.
   *
   * @throws Exception
   *           If an unexpected error occurred.
   */
  @Test
  public void testCreateChildManagedObjectDefault() throws Exception {
    CreateEntryMockLDAPConnection c = new CreateEntryMockLDAPConnection(
        "cn=test child 3,cn=test-children,cn=test parent 1,cn=test-parents");
    c.importLDIF(TEST_LDIF);
    c.addExpectedAttribute("cn", "test child 3");
    c.addExpectedAttribute("objectclass", "top", "ds-cfg-test-child");
    ManagementContext ctx = LDAPManagementContext.createFromContext(c,
        new MockLDAPProfile());
    TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
    parent.createTestChild(TestChildCfgDefn.getInstance(), "test child 3",
        new MockPropertyProvider());
    c.assertEntryIsCreated();
  }
  /**
   * Tests creation of a top-level managed object using fails when an
   * underlying NamingException occurs.
   *
   * @param cause
   *          The NamingException cause of the failure.
   * @param expected
   *          The expected client API exception class.
   */
  @Test(dataProvider = "createManagedObjectExceptions")
  public void testCreateManagedObjectException(final NamingException cause,
      Class<? extends Exception> expected) {
    MockLDAPConnection c = new MockLDAPConnection() {
      /**
       * {@inheritDoc}
       */
      @Override
      public void createEntry(LdapName dn, Attributes attributes)
          throws NamingException {
        throw cause;
      }
    };
    c.importLDIF(TEST_LDIF);
    ManagementContext ctx = LDAPManagementContext.createFromContext(c,
        new MockLDAPProfile());
    try {
      createTestParent(ctx, "test parent 3", new MockPropertyProvider());
    } catch (Exception e) {
      Assert.assertEquals(e.getClass(), expected);
    }
  }
  /**
   * Tests creation of a top-level managed object.
   *
   * @throws Exception
   *           If an unexpected error occurred.
   */
  @Test
  public void testCreateTopLevelManagedObject() throws Exception {
    MockPropertyProvider p = new MockPropertyProvider();
    CreateEntryMockLDAPConnection c = new CreateEntryMockLDAPConnection(
        "cn=test parent 3,cn=test-parents");
    c.importLDIF(TEST_LDIF);
    c.addExpectedAttribute("cn", "test parent 3");
    c.addExpectedAttribute("objectclass", "top", "ds-cfg-test-parent");
    p.addProperty("maximum-length", "54321");
    c.addExpectedAttribute("ds-cfg-maximum-length", "54321");
    p.addProperty("minimum-length", "12345");
    c.addExpectedAttribute("ds-cfg-minimum-length", "12345");
    ManagementContext ctx = LDAPManagementContext.createFromContext(c,
        new MockLDAPProfile());
    createTestParent(ctx, "test parent 3", p);
    c.assertEntryIsCreated();
  }
  /**
   * Tests creation of a top-level managed object.
   *
   * @throws Exception
   *           If an unexpected error occurred.
   */
  @Test
  public void testCreateTopLevelManagedObjectDefault() throws Exception {
    CreateEntryMockLDAPConnection c = new CreateEntryMockLDAPConnection(
        "cn=test parent 3,cn=test-parents");
    c.importLDIF(TEST_LDIF);
    c.addExpectedAttribute("cn", "test parent 3");
    c.addExpectedAttribute("objectclass", "top", "ds-cfg-test-parent");
    ManagementContext ctx = LDAPManagementContext.createFromContext(c,
        new MockLDAPProfile());
    createTestParent(ctx, "test parent 3", new MockPropertyProvider());
    c.assertEntryIsCreated();
  }
  /**
   * Tests retrieval of a child managed object with non-default
   * values.
   *
   * @throws Exception
   *           If an unexpected error occurred.
   */
  @Test
  public void testGetChildManagedObject() throws Exception {
    ManagementContext ctx = getManagementContext(TEST_LDIF);
    TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
    TestChildCfgClient child = parent.getTestChild("test child 2");
    Assert.assertEquals(child.getHeartbeatInterval(), 12345000);
  }
  /**
   * Tests retrieval of a child managed object with default values.
   *
   * @throws Exception
   *           If an unexpected error occurred.
   */
  @Test
  public void testGetChildManagedObjectDefault() throws Exception {
    ManagementContext ctx = getManagementContext(TEST_LDIF);
    TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
    TestChildCfgClient child = parent.getTestChild("test child 1");
    Assert.assertEquals(child.getHeartbeatInterval(), 1000);
  }
  /**
   * Tests retrieval of a top-level managed object using fails when an
   * underlying NamingException occurs.
   *
   * @param cause
   *          The NamingException cause of the failure.
   * @param expected
   *          The expected client API exception class.
   */
  @Test(dataProvider = "getManagedObjectExceptions")
  public void testGetManagedObjectException(final NamingException cause,
      Class<? extends Exception> expected) {
    MockLDAPConnection c = new MockLDAPConnection() {
      /**
       * {@inheritDoc}
       */
      @Override
      public Attributes readEntry(LdapName dn, Collection<String> attrIds)
          throws NamingException {
        throw cause;
      }
    };
    c.importLDIF(TEST_LDIF);
    ManagementContext ctx = LDAPManagementContext.createFromContext(c,
        new MockLDAPProfile());
    try {
      getTestParent(ctx, "test parent 2");
    } catch (Exception e) {
      Assert.assertEquals(e.getClass(), expected);
    }
  }
  /**
   * Tests retrieval of a top-level managed object with non-default
   * values.
   *
   * @throws Exception
   *           If an unexpected error occurred.
   */
  @Test
  public void testGetTopLevelManagedObject() throws Exception {
    ManagementContext ctx = getManagementContext(TEST_LDIF);
    TestParentCfgClient parent = getTestParent(ctx, "test parent 2");
    Assert.assertEquals(parent.getMinimumLength(), 10000);
    Assert.assertEquals(parent.getMaximumLength(), 20000);
  }
  /**
   * Tests retrieval of a top-level managed object with default
   * values.
   *
   * @throws Exception
   *           If an unexpected error occurred.
   */
  @Test
  public void testGetTopLevelManagedObjectDefault() throws Exception {
    ManagementContext ctx = getManagementContext(TEST_LDIF);
    TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
    Assert.assertEquals(parent.getMinimumLength(), 123);
    Assert.assertEquals(parent.getMaximumLength(), 456);
  }
  /**
   * Tests listing of child managed objects.
   *
   * @throws Exception
   *           If an unexpected error occurred.
   */
  @Test
  public void testListChildManagedObjects() throws Exception {
    ManagementContext ctx = getManagementContext(TEST_LDIF);
    TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
    String[] actual = parent.listTestChildren();
    String[] expected = new String[] { "test child 1", "test child 2" };
    Assert.assertEqualsNoOrder(actual, expected);
  }
  /**
   * Tests listing of child managed objects when their are not any.
   *
   * @throws Exception
   *           If an unexpected error occurred.
   */
  @Test
  public void testListChildManagedObjectsEmpty() throws Exception {
    ManagementContext ctx = getManagementContext(TEST_LDIF);
    TestParentCfgClient parent = getTestParent(ctx, "test parent 2");
    String[] actual = parent.listTestChildren();
    String[] expected = new String[] {};
    Assert.assertEqualsNoOrder(actual, expected);
  }
  /**
   * Tests listing of top level managed objects.
   *
   * @throws Exception
   *           If an unexpected error occurred.
   */
  @Test
  public void testListTopLevelManagedObjects() throws Exception {
    ManagementContext ctx = getManagementContext(TEST_LDIF);
    String[] actual = listTestParents(ctx);
    String[] expected = new String[] { "test parent 1", "test parent 2" };
    Assert.assertEqualsNoOrder(actual, expected);
  }
  /**
   * Tests listing of top level managed objects when their are not
   * any.
   *
   * @throws Exception
   *           If an unexpected error occurred.
   */
  @Test
  public void testListTopLevelManagedObjectsEmpty() throws Exception {
    ManagementContext ctx = getManagementContext();
    String[] actual = listTestParents(ctx);
    String[] expected = new String[] {};
    Assert.assertEqualsNoOrder(actual, expected);
  }
  /**
   * Tests modification of a child managed object.
   *
   * @throws Exception
   *           If an unexpected error occurred.
   */
  @Test
  public void testModifyChildManagedObjectResetToDefault() throws Exception {
    ModifyEntryMockLDAPConnection c = new ModifyEntryMockLDAPConnection(
        "cn=test child 2,cn=test-children,cn=test parent 1,cn=test-parents");
    c.importLDIF(TEST_LDIF);
    c.addExpectedModification("ds-cfg-heartbeat-interval");
    ManagementContext ctx = LDAPManagementContext.createFromContext(c,
        new MockLDAPProfile());
    TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
    TestChildCfgClient child = parent.getTestChild("test child 2");
    child.setHeartbeatInterval(null);
    child.commit();
    Assert.assertTrue(c.isEntryModified());
  }
  /**
   * Tests modification of a top-level managed object.
   *
   * @throws Exception
   *           If an unexpected error occurred.
   */
  @Test
  public void testModifyTopLevelManagedObjectNoChanges() throws Exception {
    ModifyEntryMockLDAPConnection c = new ModifyEntryMockLDAPConnection(
        "cn=test parent 1,cn=test-parents");
    c.importLDIF(TEST_LDIF);
    ManagementContext ctx = LDAPManagementContext.createFromContext(c,
        new MockLDAPProfile());
    TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
    parent.commit();
    Assert.assertFalse(c.isEntryModified());
  }
  /**
   * Tests modification of a top-level managed object.
   *
   * @throws Exception
   *           If an unexpected error occurred.
   */
  @Test
  public void testModifyTopLevelManagedObjectWithChanges() throws Exception {
    ModifyEntryMockLDAPConnection c = new ModifyEntryMockLDAPConnection(
        "cn=test parent 1,cn=test-parents");
    c.importLDIF(TEST_LDIF);
    c.addExpectedModification("ds-cfg-maximum-length", "54321");
    c.addExpectedModification("ds-cfg-minimum-length", "12345");
    ManagementContext ctx = LDAPManagementContext.createFromContext(c,
        new MockLDAPProfile());
    TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
    parent.setMaximumLength(54321);
    parent.setMinimumLength(12345);
    parent.commit();
    Assert.assertTrue(c.isEntryModified());
  }
  /**
   * Tests removal of a child managed object.
   *
   * @throws Exception
   *           If an unexpected error occurred.
   */
  @Test
  public void testRemoveChildManagedObject() throws Exception {
    DeleteSubtreeMockLDAPConnection c = new DeleteSubtreeMockLDAPConnection(
        "cn=test child 1,cn=test-children,cn=test parent 1,cn=test-parents");
    c.importLDIF(TEST_LDIF);
    ManagementContext ctx = LDAPManagementContext.createFromContext(c,
        new MockLDAPProfile());
    TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
    parent.removeTestChild("test child 1");
    c.assertSubtreeIsDeleted();
  }
  /**
   * Tests removal of a top-level managed object.
   *
   * @throws Exception
   *           If an unexpected error occurred.
   */
  @Test
  public void testRemoveTopLevelManagedObject() throws Exception {
    DeleteSubtreeMockLDAPConnection c = new DeleteSubtreeMockLDAPConnection(
        "cn=test parent 1,cn=test-parents");
    c.importLDIF(TEST_LDIF);
    ManagementContext ctx = LDAPManagementContext.createFromContext(c,
        new MockLDAPProfile());
    removeTestParent(ctx, "test parent 1");
    c.assertSubtreeIsDeleted();
  }
  // Create the named test parent managed object.
  private void createTestParent(ManagementContext context, String name,
      PropertyProvider p) throws ManagedObjectDecodingException,
      AuthorizationException, ManagedObjectAlreadyExistsException,
      ConcurrentModificationException, OperationRejectedException,
      CommunicationException {
    ManagedObject<RootCfgClient> root = context
        .getRootConfigurationManagedObject();
    root.createChild(TestParentCfgDefn.RD_TEST_PARENT, TestParentCfgDefn
        .getInstance(), name, p);
  }
  // Creates a management context using the provided LDIF.
  private ManagementContext getManagementContext(String... ldif) {
    MockLDAPConnection c = new MockLDAPConnection();
    c.importLDIF(ldif);
    return LDAPManagementContext.createFromContext(c, new MockLDAPProfile());
  }
  // Retrieve the named test parent managed object.
  private TestParentCfgClient getTestParent(ManagementContext context,
      String name) throws DefinitionDecodingException,
      ManagedObjectDecodingException, AuthorizationException,
      ManagedObjectNotFoundException, ConcurrentModificationException,
      CommunicationException {
    ManagedObject<RootCfgClient> root = context
        .getRootConfigurationManagedObject();
    return root.getChild(TestParentCfgDefn.RD_TEST_PARENT, name)
        .getConfiguration();
  }
  // List test parent managed objects.
  private String[] listTestParents(ManagementContext context)
      throws AuthorizationException, ConcurrentModificationException,
      CommunicationException {
    ManagedObject<RootCfgClient> root = context
        .getRootConfigurationManagedObject();
    return root.listChildren(TestParentCfgDefn.RD_TEST_PARENT);
  }
  // Remove the named test parent managed object.
  private void removeTestParent(ManagementContext context, String name)
      throws AuthorizationException, ManagedObjectNotFoundException,
      OperationRejectedException, ConcurrentModificationException,
      CommunicationException {
    ManagedObject<RootCfgClient> root = context
        .getRootConfigurationManagedObject();
    root.removeChild(TestParentCfgDefn.RD_TEST_PARENT, name);
  }
}
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/MockLDAPConnection.java
New file
@@ -0,0 +1,358 @@
/*
 * 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/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * 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/opends/resource/legal-notices/OpenDS.LICENSE.  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
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.server.admin.client.ldap;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.naming.NameNotFoundException;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.BasicAttributes;
import javax.naming.ldap.LdapName;
import org.opends.server.TestCaseUtils;
import org.opends.server.types.AttributeValue;
import org.opends.server.types.DN;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.Entry;
import org.opends.server.types.RDN;
import org.testng.Assert;
/**
 * A mock LDAP connection which fakes up search results based on some
 * LDIF content. Implementations should override the modify operations
 * in order to get provide the correct fake behavior.
 */
public class MockLDAPConnection extends LDAPConnection {
  /**
   * A mock entry.
   */
  private static final class MockEntry {
    // The entry's attributes.
    private final Attributes attributes;
    // The entry's children.
    private final List<MockEntry> children;
    // The name of this mock entry.
    private final DN dn;
    /**
     * Create a new mock entry with the provided name and attributes.
     *
     * @param dn
     *          The name of the entry.
     * @param attributes
     *          The attributes.
     */
    public MockEntry(DN dn, Attributes attributes) {
      this.dn = dn;
      this.attributes = attributes;
      this.children = new LinkedList<MockEntry>();
    }
    /**
     * Get the entry's attributes.
     *
     * @return Returns the entry's attributes.
     */
    public Attributes getAttributes() {
      return attributes;
    }
    /**
     * Get the entry's children.
     *
     * @return Returns the entry's children.
     */
    public List<MockEntry> getChildren() {
      return children;
    }
    /**
     * Get the entry's name.
     *
     * @return Returns the entry's name.
     */
    public DN getDN() {
      return dn;
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public String toString() {
      StringBuilder builder = new StringBuilder();
      builder.append("dn=");
      builder.append(dn);
      builder.append(" attributes=");
      builder.append(attributes);
      return builder.toString();
    }
  }
  // All the entries.
  private final Map<DN, MockEntry> entries;
  // The single root entry.
  private final MockEntry rootEntry;
  /**
   * Creates a new mock LDAP connection.
   */
  public MockLDAPConnection() {
    this.rootEntry = new MockEntry(DN.nullDN(), new BasicAttributes());
    this.entries = new HashMap<DN, MockEntry>();
    this.entries.put(DN.nullDN(), this.rootEntry);
  }
  /**
   * {@inheritDoc}
   */
  public void createEntry(LdapName dn, Attributes attributes)
      throws NamingException {
    throw new UnsupportedOperationException("createEntry");
  }
  /**
   * {@inheritDoc}
   */
  public void deleteSubtree(LdapName dn) throws NamingException {
    throw new UnsupportedOperationException("deleteSubtree");
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public boolean entryExists(LdapName dn) throws NamingException {
    return getEntry(dn) != null;
  }
  /**
   * Imports the provided LDIF into this mock connection.
   *
   * @param lines
   *          The LDIF.
   */
  public final void importLDIF(String... lines) {
    try {
      for (Entry entry : TestCaseUtils.makeEntries(lines)) {
        addEntry(entry);
      }
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public Collection<LdapName> listEntries(LdapName dn) throws NamingException {
    MockEntry entry = getEntry(dn);
    if (entry == null) {
      throw new NameNotFoundException("could not find entry " + dn);
    } else {
      LinkedList<LdapName> names = new LinkedList<LdapName>();
      for (MockEntry child : entry.children) {
        names.add(new LdapName(child.getDN().toString()));
      }
      return names;
    }
  }
  /**
   * {@inheritDoc}
   */
  public void modifyEntry(LdapName dn, Attributes mods) throws NamingException {
    throw new UnsupportedOperationException("modifyEntry");
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public Attributes readEntry(LdapName dn, Collection<String> attrIds)
      throws NamingException {
    MockEntry entry = getEntry(dn);
    if (entry == null) {
      throw new NameNotFoundException("could not find entry " + dn);
    } else if (attrIds.isEmpty()) {
      return entry.getAttributes();
    } else {
      Attributes attributes = entry.getAttributes();
      Attributes filteredAttributes = new BasicAttributes();
      for (String attrId : attrIds) {
        if (attributes.get(attrId) != null) {
          filteredAttributes.put(attributes.get(attrId));
        }
      }
      return filteredAttributes;
    }
  }
  /**
   * Asserts whether the provided attribute contains exactly the set
   * of values contained in the provided collection.
   *
   * @param attr
   *          The attribute.
   * @param values
   *          The expected values.
   * @throws NamingException
   *           If an unexpected problem occurred.
   */
  protected final void assertAttributeEquals(Attribute attr,
      Collection<String> values) throws NamingException {
    LinkedList<String> actualValues = new LinkedList<String>();
    NamingEnumeration<?> ne = attr.getAll();
    while (ne.hasMore()) {
      actualValues.add(ne.next().toString());
    }
    if (actualValues.size() != values.size()
        || !actualValues.containsAll(values)) {
      Assert.fail("Attribute " + attr.getID() + " contains " + actualValues
          + " but expected " + values);
    }
  }
  /**
   * Create a new mock entry.
   *
   * @param entry
   *          The entry to be added.
   */
  private void addEntry(Entry entry) {
    MockEntry parent = rootEntry;
    DN entryDN = entry.getDN();
    // Create required glue entries.
    for (int i = 0; i < entryDN.getNumComponents() - 1; i++) {
      RDN rdn = entryDN.getRDN(entryDN.getNumComponents() - i - 1);
      DN dn = parent.getDN().concat(rdn);
      if (!entries.containsKey(dn)) {
        MockEntry glue = new MockEntry(dn, new BasicAttributes());
        parent.getChildren().add(glue);
        entries.put(dn, glue);
      }
      parent = entries.get(dn);
    }
    // We now have the parent entry - so construct the new entry.
    Attributes attributes = new BasicAttributes();
    for (org.opends.server.types.Attribute attribute : entry.getAttributes()) {
      BasicAttribute ba = new BasicAttribute(attribute.getName());
      for (AttributeValue value : attribute.getValues()) {
        ba.add(value.getStringValue());
      }
      attributes.put(ba);
    }
    // Add object classes.
    BasicAttribute oc = new BasicAttribute("objectclass");
    for (String s : entry.getObjectClasses().values()) {
      oc.add(s);
    }
    attributes.put(oc);
    MockEntry child = new MockEntry(entryDN, attributes);
    parent.getChildren().add(child);
    entries.put(entryDN, child);
  }
  /**
   * Gets the named entry.
   *
   * @param dn
   *          The name of the entry.
   * @return Returns the mock entry or <code>null</code> if it does
   *         not exist.
   */
  private MockEntry getEntry(LdapName dn) {
    DN name;
    try {
      name = DN.decode(dn.toString());
    } catch (DirectoryException e) {
      throw new RuntimeException(e);
    }
    return entries.get(name);
  }
}
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/MockPropertyProvider.java
New file
@@ -0,0 +1,111 @@
/*
 * 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/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * 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/opends/resource/legal-notices/OpenDS.LICENSE.  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
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.server.admin.client.ldap;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.opends.server.admin.PropertyDefinition;
import org.opends.server.admin.PropertyProvider;
import org.opends.server.util.Validator;
/**
 * A mock property provider which simplifies creation of managed
 * objects and LDAP attribute comparisons.
 */
public final class MockPropertyProvider implements PropertyProvider {
  // The properties.
  private final Map<String, List<String>> properties = new HashMap<String, List<String>>();
  /**
   * Default constructor.
   */
  public MockPropertyProvider() {
    // No implementation required.
  }
  /**
   * Add a property.
   *
   * @param name
   *          The name of the property.
   * @param values
   *          The property's values.
   */
  public void addProperty(String name, String... values) {
    Validator.ensureNotNull(name);
    Validator.ensureNotNull(values);
    Validator.ensureTrue(values.length > 0);
    properties.put(name, Arrays.asList(values));
  }
  /**
   * {@inheritDoc}
   */
  public <T> Collection<T> getPropertyValues(PropertyDefinition<T> d)
      throws IllegalArgumentException {
    List<String> values = properties.get(d.getName());
    if (values == null) {
      return Collections.<T> emptySet();
    }
    List<T> encodedValues = new ArrayList<T>(values.size());
    for (String value : values) {
      encodedValues.add(d.decodeValue(value));
    }
    return encodedValues;
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public String toString() {
    return properties.toString();
  }
}
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/ModifyEntryMockLDAPConnection.java
New file
@@ -0,0 +1,139 @@
/*
 * 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/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * 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/opends/resource/legal-notices/OpenDS.LICENSE.  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
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.server.admin.client.ldap;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.naming.InvalidNameException;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.ldap.LdapName;
import org.opends.server.util.Validator;
import org.testng.Assert;
/**
 * A mock LDAP connection which is used to verify that a modify
 * operation was requested and that it has the correct parameters.
 */
public final class ModifyEntryMockLDAPConnection extends MockLDAPConnection {
  // Detect multiple calls.
  private boolean alreadyModified = false;
  // The expected DN.
  private final LdapName expectedDN;
  // The expected set of modifications (attribute name -> list of
  // values).
  private final Map<String, List<String>> modifications = new HashMap<String, List<String>>();
  /**
   * Create a new mock ldap connection for detecting modify
   * operations.
   *
   * @param dn
   *          The expected DN of the entry to be added.
   */
  public ModifyEntryMockLDAPConnection(String dn) {
    try {
      this.expectedDN = new LdapName(dn);
    } catch (InvalidNameException e) {
      throw new RuntimeException(e);
    }
  }
  /**
   * Add a modification which should be part of the modify operation.
   *
   * @param expectedName
   *          The name of the expected attribute.
   * @param expectedValues
   *          The attribute's expected new values (possibly empty if
   *          deleted).
   */
  public void addExpectedModification(String expectedName,
      String... expectedValues) {
    Validator.ensureNotNull(expectedName);
    Validator.ensureNotNull(expectedValues);
    modifications.put(expectedName, Arrays.asList(expectedValues));
  }
  /**
   * Determines whether or not the entry was modified.
   *
   * @return Returns <code>true</code> if it was modified.
   */
  public boolean isEntryModified() {
    return alreadyModified;
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public void modifyEntry(LdapName dn, Attributes mods) throws NamingException {
    Assert.assertFalse(alreadyModified);
    Assert.assertEquals(dn, expectedDN);
    Map<String, List<String>> expected = new HashMap<String, List<String>>(
        modifications);
    NamingEnumeration<? extends Attribute> ne = mods.getAll();
    while (ne.hasMore()) {
      Attribute mod = ne.next();
      String attrID = mod.getID();
      List<String> values = expected.remove(attrID);
      if (values == null) {
        Assert.fail("Unexpected modification to attribute " + attrID);
      }
      assertAttributeEquals(mod, values);
    }
    if (!expected.isEmpty()) {
      Assert.fail("Missing modifications to: " + expected.keySet());
    }
    alreadyModified = true;
  }
}
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/DNBuilderTest.java
@@ -36,8 +36,15 @@
import org.opends.server.admin.ConfigurationClient;
import org.opends.server.admin.InstantiableRelationDefinition;
import org.opends.server.admin.ManagedObjectPath;
import org.opends.server.admin.MockLDAPProfile;
import org.opends.server.admin.OptionalRelationDefinition;
import org.opends.server.admin.SingletonRelationDefinition;
import org.opends.server.admin.TestChildCfg;
import org.opends.server.admin.TestChildCfgClient;
import org.opends.server.admin.TestChildCfgDefn;
import org.opends.server.admin.TestParentCfg;
import org.opends.server.admin.TestParentCfgClient;
import org.opends.server.admin.TestParentCfgDefn;
import org.opends.server.admin.std.meta.RootCfgDefn;
import org.opends.server.types.DN;
import org.testng.annotations.BeforeClass;
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/TestChildCfgDefn.java
File was deleted
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/TestParentCfgClient.java
File was deleted
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/TestParentCfgDefn.java
File was deleted