コンテンツ管理 SPI 開発ガイド

     前  次    目次  
ここから内容

SPI 実装の作成

この章では、SPI 実装の作成について説明します。節の内容は以下のとおりです。

 


VCR SPI 実装の対話

VCR は、アプリケーション リポジトリのコンフィグレーションのセットから特定のリポジトリにアクセスする必要がある時、VCR SPI リポジトリ インタフェースを実装するコンフィグレーションした SPI 実装のクラスのインスタンスをロードし、作成します。VCR は、他の VCR SPI インタフェースを実装する [Ticket] などのオブジェクトを取得するためにリポジトリ実装のメソッドを呼び出します。

VCR は、SPI 実装の機能についてクエリを送信するために [Repository] および [Ticket] 実装のメソッドを呼び出します。(機能とは、実装がサポートする操作のことです。) VCR はメソッドを呼び出して、SPI をエクスポーズする NodeOpsV1 などの操作インタフェースを取得します。最後に、VCR は操作インタフェースのメソッドを呼び出します。


基本的な SPI 実装用の主クラス

SPI 実装のための 2 つの主クラスは以下の通りです。

Repository クラスは VCR で直接にインスタンス化されます。このクラスは匿名リポジトリ アクセスを提供します。たとえば、SPI 実装は、そのバージョンおよび基本的な情報を報告できます。もっとも重要なのは、これは Ticket を取得するために SPI 実装認可のエントリ ポイントです。認可済みのユーザのみが Ticket を取得できます。Ticket を使用して重要なリポジトリ操作にアクセスできます。

Ticket は認可されたリポジトリ アクセスを提供し、NodeOpsV1 などの認可されている操作のインタフェースにアクセスすることもできます。認可済みのユーザのみが Ticket を取得することができ、Ticket を使用して重要なリポジトリ操作にアクセスにできます。このクラスは Repository.connect(…) によってインスタンス化されます。

Repository は、getAllInterfaces() および getInterface() を実装して NodeOpsV1SearchOpsV1 などの追加の認可された Ticket 操作インタフェースを必要に応じてエクスポーズできます。

実行時の一般的なフローは以下の通り。

 


SPI 実装を作成する場合のリポジトリ ガイドライン

SPI 実装を作成する場合、以下のデザインのガイドラインを使用してください。

 


基本的な SPI 実装

基本的な SPI 実装を作成するには、

  1. com.bea.content.spi.flexspi.Repository インタフェースを実装する Java クラスを作成します。
  2. このクラスは、実装する必要なインタフェースです。これは WebLogic Portal に組み込まれています。

  3. パブリック デフォルト コンストラクタを作成します。
  4. VCR によって渡されたリポジトリ コンフィグレーション プロパティを保存するために、setProperties() を実装します。ローカル変数に保存します。
  5. VCR が渡されたリポジトリ コンフィグレーション プロパティを保存するには、setName() を実装します。ローカル変数に保存します。
  6. ローカル変数を読み込むために、getProperties() および getName() を実装します。
  7. リポジトリ説明データを報告するために、getDescription() を実装します。
  8. これは、SPIDescriptionKeys にある定義したキーを持つ Properties バケットです。これには、ベンダ、バージョンなどがあります。

  9. SPI 実装がどのカスタム機能をサポートするかを報告するために、getRepositoryDefinedCapabilities() を実装します。
  10. 基本的な SPI 実装のために、Collections.emptySet() を返します。

  11. すべてのリポジトリ (ticket を除いて) 操作のインタフェースを返すには、getAllInterfaces() を実装します。
  12. これは、リポジトリが実装できる RepositoryConfigOpsV1 などのオプション インタフェースです。

    ベアボーン SPI 実装の場合、空の HashMap を返します。

  13. getAllInterfaces()と一致できるように、getInterface( String interfaceName ) を実装します。
  14. ベアボーン SPI 実装の場合、null を返します。

  15. SPI 実装がどの機能をサポートするかを報告するために、getCapabilitySupport( Set<ICapabilityDefinition> ) を実装します。
  16. オプション リポジトリ操作インタフェース全体でリポジトリがサポートするメソッド機能も報告します。

  17. コーラーが ticket を取得できるように、connect( Credentials ) および Connect( String username, String password ) を実装します。
  18. ユーザ名とパスワードが使用可能な場合、connect( username, password ) を呼び出します (通常、リポジトリ コンフィグレーション データから)。

    ユーザ名とパスワードが使用可能でない場合、connect( credentials ) を呼び出します。資格にコーラーの暗黙の ID を含みます。

    基本的な SPI 実装の場合、新しい Ticket インスタンスを作成して返します。より高度な実装は資格を認証する場合があり、成功すると Ticket インスタンスのみが返されます。

  19. RepositoryConfigOpsV1 などの省略可能な Repository 操作インタフェースを実装します。
  20. Repository.getAllInterfaces() が返されたリポジトリ操作インタフェースの場合、

    1. インタフェースを実装します。
    2. 実装されていないメソッドの場合、UnsupportedRepositoryOperationException が送出され、getCapabilitySupport() メソッドは、このメソッドはサポートされていることを報告する必要はありません。

    3. インタフェース実装が戻されるように Repository.getAllInterfaces() および getInterface() を変更します。
    4. リポジトリ操作インタフェースの各メソッドの状態 (サポートされているサポートされていない) を報告するように、Repository.getCapabilitySupport() を変更します。
  21. com.bea.content.spi.flexspi.Ticket インタフェース (WebLogic Portal と共に提供される) を実装する Java クラスを作成します。
    1. すべての Ticket 操作のインタフェースを返されるように getAllInterfaces() を実装します。これらは、Ticket が実装できる NodeOpsV1 などのオプション インタフェースです。基本的な SPI 実装の場合、空の HashMap を戻ります。
    2. getAllInterfaces() と一致するよに getInterface( String interfaceName ) を実装します。基本的な SPI 実装の場合、null のみを返します。
    3. この Ticket がオプション Ticket 操作インタフェース全体のどのメソッド機能をサポートするかを報告するために、getCapabilitySupport( Set<ICapabilityDefinition> ) を実装します。
  22. NodeOpsV1 などのオプション Ticket 操作インスタンスを実装します。
  23. Ticket.getAllInterfaces() が返される Ticket 操作インスタンスの場合、

    1. インタフェースを実装します。
    2. 実装されいないメソッドの場合、UnsupportedRepositoryOperationException が送出され、getCapabilitySupport() メソッドは、このメソッドはサポートされていることを報告する必要はありません。

    3. インタフェース実装が返されるように Ticket.getAllInterfaces() および getInterface() を変更します。
    4. リポジトリ操作インタフェースの各メソッドの状態 (サポートされているサポートされていない) を報告するように、Ticket.getCapabilitySupport() を変更します。

基本的な SPI リポジトリ実装のコード例

コード リスト 4-1 は、以下の制限があるリポジトリの簡単な SPI リポジトリ コードの例を示します。

基本的な SPI Ticket 実装のコード例

コード リスト 4-2 は、Ticket はNodeOpsV1 および SearchOpsV1 などのオプション Ticket 操作インタフェースをサポートしないので、1 つのメソッド機能はサポートしない SPI Ticket コードの例を示します。

コード リスト 4-2 Ticket 実装 コード例
import com.bea.content.spi.flexspi.Ticket;
import com.bea.content.spi.flexspi.Repository;
import com.bea.content.spi.flexspi.common.ISPIMarker;
import com.bea.content.spi.flexspi.common.SPITicketInterfaces;
import com.bea.content.spi.flexspi.common.capability.ICapabilityDefinition;
import com.bea.content.spi.flexspi.common.capability.CapabilityLevel;
import com.bea.content.spi.flexspi.common.capability.MethodCapabilityDefinition;
import java.util.*;
public class FlexTicketImpl  implements Ticket
{
   Repository repository; // この Ticket の作成に使用したリポジトリ
   //1=flex インタフェース名、2=flex インタフェース オブジェクト
   private Map<String, ISPIMarker> advertisedInterfaces;
   public FlexTicketImpl(Repository repository)  {
      this.repository = repository;
      advertisedInterfaces= new HashMap<String,ISPIMarker>();
      // まだインタフェースはない
   }
   public Map<String, ISPIMarker> getAllInterfaces() {
      return advertisedInterfaces;
   }
   public ISPIMarker getInterface(String interfaceName) {
      return advertisedInterfaces.get(interfaceName);
   }
   public Map<ICapabilityDefinition, CapabilityLevel>
      getCapabilitySupport(Set<ICapabilityDefinition> capabilities)
   {
      // インタフェース、メソッド、機能すべてはサポートされていません
      HashMap<ICapabilityDefinition, CapabilityLevel> capMap 
         =new HashMap<ICapabilityDefinition, CapabilityLevel>();
   // サポートされていないすべての項目から開始し、
   // サポートされる個々の機能をマークします。
   for (ICapabilityDefinition capDef : capabilities) {
      capMap.put(capDef, CapabilityLevel.NotSupported);
   }
         // 以前サポートされていない機能はサポートする場合、
         // サポートされなかった値がオーバーライドされます
         // すべてはサポートされていません 
         return capMap;
   }
}


省略可能な SPI インタフェース実装

VCR にノードとタイプをエクスポーズするために、省略可能な SPI インタフェースを使用します。一般的に、クライアントコードはコードに対して実行されるリポジトリの機能について特定な仮定があります (たとえば、ノードへの読み取り専用アクセス)。VCR はノードとタイプをリポジトリに委託するので、クライアント コードは特定の VCR メソッドが適切に動作することを前提とします。

省略可能な PSPI インタフェースは以下の通り。

省略可能な SPI インタフェースのエクスポーズ

NodeOpsV1 などの省略可能な SPI インタフェースをエクスポーズするには、

  1. SPI インタフェースを実装するには、クラスを作成します。
  2. たとえば、MyNodeOpsNodeOpsV1 を実装します。一般に、多数のオブジェクトが作成される場合があるので、軽量のクラスを作成する必要があります。

  3. SPI インタフェース メソッドの実装を記述します。
  4. 注意 : 実装されていないのメソッドの場合、UnsupportedRepositoryOperationException が送出されます。また、Ticket.getCapabilitySupport() メソッドは、このメソッドはサポートされていることを報告する必要があります。
  5. インタフェース実装が返されるように Ticket.getAllInterfaces() および getInterface() を変更します。
  6. オブジェクトの作成を減らすには、Ticket の作成時にインタフェースを作成して保持し、getAllInterfaces() および getInterface() に返します。次に例を示します。

    private Map<String,ISPIMarker> ifaces;
    public FlexTicketImpl( Repository repository ) {
       this.repository= repository;
    //init インタフェース
       ifaces= new HashMap<String,ISPIMarker>();
       ifaces.put(SPITicketInterfaces.NODE_OPS_V1,
          new MyNodeOps(…);
    . . .
    }

    public Map<String, ISPIMarker> getAllInterfaces() {
       return ifaces;
    }
    public ISPIMarker getInterface( String ifaceName ) {
       return ifaces.get( ifaceName );
    }
  7. すべての Ticket 操作インタフェースの各メソッドの状態 (サポートされているサポートされていない) を報告するように、Ticket.getCapabilitySupport() を変更します。次に例を示します。
  8. public Map<ICapabilityDefinition, CapabilityLevel>
       getCapabilitySupport(Set<ICapabilityDefinition> capabilities)
    {
       Map<ICapabilityDefinition, CapabilityLevel> capMap
          =new HashMap<ICapabilityDefinition, CapabilityLevel>();
       // サポートされていないすべての項目から開始し、
       // サポートされる個々の機能をマークします。
       for (ICapabilityDefinition capDef : capabilities) {
          capMap.put(capDef, CapabilityLevel.NotSupported);
       }
       // 必要に応じてサポートされていない値をオーバーライドします
       final String[] supportedNodeOpsMethodNames = new String[] {
          NodeOpsV1.MethodName.getNodeChildren.toString(),
          NodeOpsV1.MethodName.getNodeChildrenAsNodeIds.toString(),
          NodeOpsV1.MethodName.getNodesWithIds.toString(),
          NodeOpsV1.MethodName.getNodeWithId.toString(),
          NodeOpsV1.MethodName.getNodeWithPath.toString(),
       };
       for (String methodName : supportedNodeOpsMethodNames) {
          ICapabilityDefinition capDef
             = new MethodCapabilityDefinition(
                SPITicketInterfaces.NODE_OPS, methodName
                );
             if (capabilities.contains(capDef)) {
                capMap.put(capDef, CapabilityLevel.FullySupported);
          }
       }
       return capMap;
    }

 


SPI インタフェース 結果の集合、ソーティングおよびフィルタリング

オプションで、SPI 実装では結果をソートおよびフィルタするの機能を含むことができます。SPI が返された項目の集合を QueryResult オブジェクト (結果の順序付きリストを含む) および返された集合のソートとフィルタの方法を (処理を行う場合) 記述する QueryCriteria オブジェクトに返します。たとえば、QueryResult<Node> には、ソートおよびフィルタしたノードの集合を含む場合があります。

SPI を使用して結果のフィルタおよびソート処理

結果の集合を返す多数のメソッドは QueryCriteria パラメータを使用します。このパラメタでコーラーは結果のソートまたはフィルタ方法 (可能であれは両方も) を設定できます。たとえば、コーラーは結果が名前によってソートされるよう要求する場合があります。現在、コーラーは 1 つのソート条件および 1 つのフィルタ条件のみを指定できます。

SortCriteriaには、名前昇順 などのプロパティ (条件) および昇順または降順フラグがあります。

FilterCriteria には、プロパティ (条件) とフィルターなし、等しい、等しくない、含む、含まない、で始まる、で終わる、より大きい、より小さいおよび値などの FilterMethod オペランドがあります。たとえば、name contains 'foo'

プロパティのソートおよびフィルタ条件のセットは使用しているデータ オブジェクトの JavaBean プロパティに関連付けられます。たとえば、Node には getName() メソッドがあるので name および getCreatedDate() メソッドがあるので createdDate のために JavaBean プロパティを含みます。

ネイティブのソート、フィルタ処理はうまく機能します。また、SPI 実装がソートまたはフィルタの要求を処理できない場合、VCR はメモリ内にソーティングとフィルタリングを行うためにメカニズムをサポートします。クライアント コード (と VCR) は、SPI がネイティブにソートおよびフィルタできるプロパティを確認できます。

SPI 実装は NodeOpsV1.getNativeSortableProperties() および NodeOpsV1.getNativeFilterableProperties() などのメソッドを実装して、インタフェースのオブジェクトのために VCR にそのソーティングおよびフィルタリング機能 (ソートおよびフィルタできるプロパティ) を報告します。たとえば、SPI はノードが name および createDate プロパティでソートできることを報告します。

ソーティングおよびフィルタリング機能の報告は実際にインタフェース精度で行っています。つまり、NodeOpsV1 などの特定のインタフェースには主なデータ オブジェクトがあります。主なデータ オブジェクト、たとえば、Node は、インタフェースでの結果の集合メソッド全体でソート、フィルタ処理の機能を報告します。

ヒント : SPI がネイティブのソートまたはフィルタ処理をサポートしていない場合、null ではなく、Collections.emptySet() などの空セットを返す必要があります。

SPI 実装は、サポートするソーティングとフィルタリング機能よりも高度な機能を要求する QueryCriteria パラメタを受信する場合があります。この場合に、SPI 実装は例外を送出しないことを確認します。代わりに、SPI 実装は結果をソートおよびフィルタする現在の方法を報告する必要があります。たとえば、SPI 実装は、未ソートと未フィルタ QueryResult を作成して、ソートとフィルタできなかった項目を表します。SPI 実装が 1 つの要求を実行できる場合、要求を実行して適切に結果を報告する必要があります。たとえば、ソートすることができる場合、SPI 実装は結果を [ソート済みが未フィルタ] として報告する必要があります。

必要に応じて、VCR はクライアントの要求によってソートまたはフィルタ処理を行っているかを確認するために、メモリ内でクエリ結果をソートまたはフィルタする場合があります。

ソートおよびフィルタの対象である共通の SPI インタフェース オブジェクト

ソートおよびフィルタ処理を行うために以下のオブジェクトを使用します。


  ページの先頭       前  次