モジュール java.naming

パッケージ javax.naming.ldap

LDAPv3の拡張操作とコントロールのサポートを提供します。

このパッケージは、Java Naming and Directory Interface™ (JNDI)のディレクトリ操作を拡張します。   JNDIは、Javaプログラミング言語で記述されたアプリケーションにネーミングおよびディレクトリ機能を提供します。 ほかのネームおよびディレクトリ・サービスの実装と独立して動作するように設計されています。 新しいサービス、展開されつつあるサービス、すでに展開されているサービスなど、さまざまなサービスに対して共通の方法でアクセスすることができます。

このパッケージは、RFC 2251で定義されたLDAPv3の拡張操作とコントロールを処理するアプリケーションおよびサービス・プロバイダ向けのものです。 このパッケージのコア・インタフェースはLdapContextで、これは拡張操作実行およびコントロール処理のコンテキストのメソッドを定義します。

拡張操作

このパッケージは、拡張操作の引数を表すExtendedRequestインタフェースおよび拡張操作の結果を表すExtendedResponseインタフェースを定義します。 拡張応答は常に拡張要求とペアになりますが、拡張要求は必ずしも拡張応答とペアになる必要はありません。 つまり、対応する拡張応答のない拡張要求を持てるということです。

アプリケーションは通常、これらのインタフェースを直接は処理しません。 代わりに、これらのインタフェースを実装しているクラスが処理されます。 これらのクラスは、IETFによって標準化された拡張操作のレパートリの一部として取得しますが、ベンダー固有の拡張操作の場合はディレクトリ・ベンダーから取得します。 要求クラスには、型保証された簡単な方法で引数を受け取るコンストラクタが必要です。また、応答クラスには、同様の方法で応答のデータを取得するアクセス・メソッドが必要です。 要求および応答クラスでは、BER値のエンコードおよびデコードが行われます。

たとえば、LDAPサーバーが「時間取得」の拡張操作をサポートしているとします。 それは、アプリケーションでこの機能が使用できるように、GetTimeRequestGetTimeResponseなどのクラスを提供します。 アプリケーションはこれらのクラスを次のように使います。

GetTimeResponse resp =
    (GetTimeResponse) ectx.extendedOperation(new GetTimeRequest());
long time = resp.getTime();

GetTimeRequestおよびGetTimeResponseクラスは次のように定義できます。

public class GetTimeRequest implements ExtendedRequest {
    // User-friendly constructor 
    public GetTimeRequest() {
    };

    // Methods used by service providers
    public String getID() {
        return GETTIME_REQ_OID;
    }
    public byte[] getEncodedValue() {
        return null;  // no value needed for get time request
    }
    public ExtendedResponse createExtendedResponse(
        String id, byte[] berValue, int offset, int length) throws NamingException {
        return new GetTimeResponse(id, berValue, offset, length);
    }
}
public class GetTimeResponse() implements ExtendedResponse {
    long time;
    // called by GetTimeRequest.createExtendedResponse()
    public GetTimeResponse(String id, byte[] berValue, int offset, int length)
        throws NamingException {
        // check validity of id
        long time =  ... // decode berValue to get time
    }

    // Type-safe and User-friendly methods
    public java.util.Date getDate() { return new java.util.Date(time); }
    public long getTime() { return time; }

    // Low level methods
    public byte[] getEncodedValue() {
        return // berValue saved;
    }
    public String getID() {
        return GETTIME_RESP_OID;
    }
}

コントロール

このパッケージは、LDAPv3コントロールを表すControlインタフェースを定義します。 このインタフェースは、LDAPサーバーに送信されるコントロール(要求コントロール)となるか、あるいはLDAPサーバーによって返されるコントロール(応答コントロール)となります。 拡張要求や拡張応答と異なり、必ずしも要求コントロールと応答コントロールの間にペアを組む必要はありません。 要求コントロールを送信して応答コントロールが戻らないようにしたり、あるいは要求コントロールを送信しないで応答コントロールを受信したりできます。

アプリケーションは通常、このインタフェースを直接は処理しません。 代わりに、このインタフェースを実装しているクラスを処理します。 アプリケーションはコントロール・クラスを、IETFによって標準化されたコントロールのレパートリの一部として取得するか、あるいはベンダー固有のコントロールのディレクトリ・ベンダーから取得します。 要求コントロール・クラスには、型保証されたユーザーが使いやすい方法で引数を受け入れるコンストラクタが必要で、応答コントロール・クラスには、型保証されたユーザーが使いやすい方法で応答のデータを取得するためのアクセス・メソッドが必要です。 内部的には、要求コントロール・クラスおよび応答コントロール・クラスはBER値のエンコードおよびデコードを処理します。

たとえば、LDAPサーバーが「署名付き結果」の要求コントロールをサポートしているとします。このコントロールは、要求とともに送信されたとき、サーバーに、電子署名付きで操作結果を返すように要求します。 それは、アプリケーションがこの機能を使えるよう、SignedResultsControlクラスを指定します。 アプリケーションはこのクラスを次のように使います。

Control[] reqCtls = new Control[] {new SignedResultsControl(Control.CRITICAL)};
ectx.setRequestControls(reqCtls);
NamingEnumeration enum = ectx.search(...);
SignedResultsControlクラスは次のように定義できます。
public class SignedResultsControl implements Control {
    // User-friendly constructor 
    public SignedResultsControl(boolean criticality) {
        // assemble the components of the request control
    };

    // Methods used by service providers
    public String getID() {
        return // control's object identifier
    }
    public byte[] getEncodedValue() {
        return // ASN.1 BER encoded control value
    }
    ...
}

サービス・プロバイダが応答コントロールを受信すると、このプロバイダはControlFactoryクラスを使って、Controlインタフェースを実装する特定のクラスを生成します。

LDAPサーバーは、LDAP操作とともに応答コントロールを返信でき、またリストや検索操作などによって返された列挙結果とともに返信できます。 LdapContextは、LDAP操作とともに送信された応答コントロールを取得するメソッド(getResponseControls())を提供し、HasControlsインタフェースは、列挙結果に関連した応答コントロールを取得するのに使用されます。

たとえば、変更完了にともないLDAPサーバーが「ID変更」コントロールを返信するとします。 サーバーは、アプリケーションがこの機能を使えるようにChangeIDControlクラスを指定します。 アプリケーションは更新を行い、続いてID変更を取得しようとします。

// Perform update
Context ctx = ectx.createSubsubcontext("cn=newobj");

// Get response controls
Control[] respCtls = ectx.getResponseControls();
if (respCtls != null) {
    // Find the one we want
    for (int i = 0; i < respCtls; i++) {
        if(respCtls[i] instanceof ChangeIDControl) {
            ChangeIDControl cctl = (ChangeIDControl)respCtls[i];
            System.out.println(cctl.getChangeID());
        }
    }
}
ベンダーは次のようなChangeIDControlクラスおよびVendorXControlFactoryクラスを指定します。 サービス・プロバイダは、LDAPサーバーから応答コントロールを受信したとき、VendorXControlFactoryを使用します。
public class ChangeIDControl implements Control {
    long id;

    // Constructor used by ControlFactory
    public ChangeIDControl(String OID, byte[] berVal) throws NamingException {
        // check validity of OID
        id = // extract change ID from berVal
    };

    // Type-safe and User-friendly method
    public long getChangeID() {
        return id;
    }

    // Low-level methods
    public String getID() {
        return CHANGEID_OID;
    }
    public byte[] getEncodedValue() {
        return // original berVal
    }
    ...
}
public class VendorXControlFactory extends ControlFactory {
    public VendorXControlFactory () {
    }

    public Control getControlInstance(Control orig) throws NamingException {
        if (isOneOfMyControls(orig.getID())) {
            ...

            // determine which of ours it is and call its constructor
            return (new ChangeIDControl(orig.getID(), orig.getEncodedValue()));
        }
        return null;  // not one of ours
    }
}

パッケージの仕様

JNDI APIの仕様と関連ドキュメントについては、「JNDIのドキュメント」を参照してください。
導入されたバージョン:
1.3