カスタム参照実装からのメタデータの取得

Business Components for Javaフレームワークの柔軟性の多くは、メタデータ駆動のアーキテクチャによるものです。ビジネス・コンポーネントのメタデータはXMLで記述され、コンポーネントの実装はJavaのクラスで提供されます。

デフォルトでは、フレームワークは、CLASSPATHでリソースであるXMLファイルを検索し、XMLコンポーネント定義ファイルを検出します。ただし、カスタム・メタデータの参照実装を用意すれば、どこからでもメタデータを取得できます。

次の図は、ビジネス・コンポーネント・メタデータ参照に関連するクラスおよびインタフェースを示します。

Figure that shows CustomXMLContextImpl, which extends XMLContextImpl, which implements XMLContext,   which extends Context. CustomContextImpl implements XMLContext. MetaObjectManager creates and uses XMLContext.

oracle.apps.requisition.LineItemという名前のコンポーネントのメタデータ参照を要求した場合、getMetaDataStream()メソッドのデフォルトの実装は、getResourceAsStream()をコールしてCLASSPATHからファイル/oracle/apps/requisition/LineItem.xmlを開きます。

カスタム・メタデータ参照メカニズムを提供するには、oracle.jbo.server.xml.XMLContextインタフェースを実装するクラスを用意する必要があります。利便性を高めるために、このクラスのベース実装がoracle.jbo.server.xml.XMLContextImplに用意されています。これを拡張することでXMLContextインタフェースの各メソッドの実装を記述する必要がなくなります。

大部分のカスタム参照は、XMLContextImplを拡張し、次のメソッドをオーバーライドすることで実現します。

public InputStream getMetaDataStream(url)

XMLContextImpllookupメソッドでは、XMLContextインタフェースのネームスペースのエントリに基づき、コンポーネント名の置換メカニズムを実装します。ネームスペースは、次のコールによって新規名にバインドされています。

XMLContext.bind("oldname","newname")

これは、次の要素の検出時にフレームワークでコールされます。

  <Substitutes>
  <Substitute OldName="x.y.Department" NewName="q.p.NewDepartment"/>
  <Substitute OldName="a.b.Employee" NewName="c.e.Employee"/>
  </Substitutes>

これは、/oracle/jbo/server/jboserver.propertiesプロパティ・ファイルのFactory-Substitution-Listプロパティ値に指定されている名前のプロジェクト・ファイル(*.jpx)にあります。

注意: Factory-Substitution-Listは、
-Djbo.project=mypackage.MyProject オプションを使用してコマンドラインから設定できます。

現在、参照実装はコンポーネント名をURLパス名にも変換します。フレームワークが次のコンポーネント名のlookupを要求したとします。

oracle.apps.requisition.LineItem

この要求は次の文字列としてgetMetaDataStreamに渡されます。

/oracle/apps/requisition/LineItem.xml

また、フレームワークが次のようなプロジェクト・メタデータ・ファイルの参照を要求したとします。

mypackage.MyProject.jpx

この要求は次の文字列としてgetMetaDataStreamに渡されます。

/mypackage/MyProject.jpx

注意: 今後のリリースでは、lookupは、oracle.apps.requisition.LineItemなどの置換されたパッケージ名を、参照実装の一部としてURLパス名に変換せずに返す可能性があります。次のいずれかの方法でそれに備えることができます。

getMetaDataStream実装で、すでにコンポーネントをURL名に変換する(または、ランタイム・ディクショナリの主キー同様、この形式で使用する)ようにしてある場合、次のような簡単なgetMetaDataStreamの実装を用意します。

import oracle.jbo.server.xml.XMLContextImpl;
import java.util.Hashtable;
import java.net.*;
import java.io.*;
public class HTTPXMLContextImpl extends XMLContextImpl {
  public HTTPXMLContextImpl(Hashtable env) {
  super(env);
  }
  public InputStream getMetaDataStream(String name) {
  String urlBase = "http://metadataserver.company.com";
  InputStream iStr = null;
  try {
  iStr = (new URL( urlBase + name )).openStream();
  }
  catch (MalformedURLException m) { return null; }
  catch (IOException i) { return null; }
  return iStr;
  }
}

これは、カスタムXMLContextの非常に簡単な実装です。この実装は、次のようなコンポーネントのメタデータをフェッチするデフォルトの動作をオーバーライドします。

oracle.apps.requisition.LineItem

このコンポーネントの名前は、次の名前でgetMetaDataStreamに渡されます。

/oracle/apps/requisition/LineItem.xml

これを渡すのは、次のURLのWebサーバーです。

http://metadataserver.company.com/oracle/apps/requisition/LineItem.xml

もちろん、実装をより高度にし、任意のサービスにメタデータをリクエストすることもできます。このサービスでは、データベース駆動のランタイム・ディクショナリ情報に基づき、ビジネス・コンポーネントXMLメタデータを動的に実現することもできます。

カスタム実装クラスを作成した後、ビジネス・コンポーネント・ランタイムに、デフォルトでなはく、独自の実装を使用するよう指定する必要があります。これは、./oracle/jbo/server/jboserver.propertiesファイル内のMetaObjectContextプロパティの値を設定することにより指定できます。デフォルトでは、このファイルは、OracleホームのBC4J/libディレクトリのbc4jmt.jarアーカイブ内に格納されています。

次に、jboserver.propertiesファイルを例として示します。このファイルは編集され、前述のサンプル、HTTPXMLContextImplクラスを使用するようMetaObjectContextプロパティが設定され、ファクトリ置換リストの検索にmypackage.SomeProjectプロジェクト・ファイルを使用するようFactory-Substitution-Listプロパティが設定されています。

# ------------------------------------------------------------------------
# File: oracle.jbo.server.jboserver.properties
# Cont: JBO Runtime Property Definitions
# Desc:
# ------------------------------------------------------------------------
# XML Context Factory and context for Meta Object lookup.
MetaObjectContextFactory = oracle.jbo.server.xml.DefaultMomContextFactory
# MetaObjectContext = oracle.jbo.server.xml.XMLContextImpl
# XML Context Customized by user : For test only
MetaObjectContext = HTTPXMLContextImpl
# Is lazy loading property for MOM: Recommended value = true
IsLazyLoadingTrue = true
# User Substitution List through "Substitute Mechanism"
Factory-Substitution-List = mypackage.SomeProject
#SessionClass = oracle.jbo.server.SessionImpl
# Type of SQLBuilder interface to load
jbo.SQLBuilder = Oracle
#jbo.SQLBuilder = OLite
# ------------------------------------------------------------------------
# end of file
# ------------------------------------------------------------------------