目次 | |

8. 自己検査

8.1 概観

実行時及びビルダ環境では,Java Beanが,どの特性, イベント及びメソッドをサポートするかを,見つけ出すことができる必要がある。 この過程を,自己検査(introspection)と呼ぶ。

Java Beans開発者が,Javaで,十分に作業を行えることが望ましい。 そこで,Java Beanの振舞いを定義するために,いかなる別の仕様記述言語の使用も避けたい。 Javaで,その振舞いをすべて指定したい。

Java Beansの主要目標は,単純な部品を書くこと 及び大部分の共通タスクに対しデフォルトの実装を提供することを,非常に容易にすることにある。 そのため,単純なビーンズでは,ビーンズ開発者が, 自己検査をサポートするための一連の余分な作業を行わずに,自己検査をできるようにしたい。 しかし,より複雑な部品に対しても,部品開発者が,特性,イベント及びメソッドの公開に関して, 完全及び正確な制御ができるようにしたい。

そのために,複合的な機構を提供する。 デフォルトでは,低レベルの 自己反映(reflection) 機構を使用して, 対象ビーンがサポートするメソッドを調べ,その後,単純な 設計パタン(design pattern) を適用して,これらのメソッドから, 特性,イベント及び公開メソッドのいずれがサポートされているかを導き出す。 しかし,ビーンの実装者が,クラス BeanInfo の提供を選択し,彼らのビーンを記述する場合, このクラス BeanInfo を,ビーンの振舞いをプログラムに基づいて発見するために使用する。

アプリケーションビルダ及び他のツールが,ビーンの分析を可能とするために, 様々な設計パタン及び標準インタフェースを理解し,様々なビーンを自己検査する均一の方法を提供する, クラスIntrospectorを提供する。

任意の与えられたビーンインスタンス対して,その自己検査情報は,不変であって, 通常の使用では変化しない,と期待する。 しかし,ビーンが,クラスファイルの新しく改善された集合で更新される場合, そのシグネチャは変化するかもしれない。
 

8.2 設計パタンの概観

設計パタン(design pattern) という用語は,標準的な目的で使用するメソッド 及び/又はインタフェースの集合に対する,慣用名及び型シグネチャを意味する。 例えば,メソッドgetFoo及びメソッドsetFooは,特性“foo”の値を検索し,設定するために使用する。

これらの設計パタンには,使用法が二つある。 まず,人のプログラマにとっての有益な文書化のヒントとする。 標準設計パタンに合う特定のメソッドを素早く識別することで, 人は,新しいクラスをより速く取り入れ,使用できる。 次に,設計パタンを認識し,部品を分析及び理解するためにそれらを使用する, ツール及びライブラリを書くことができる。 特に,Java Beansでは,設計パタンの自動識別を,ツールが特性, イベント及びエクスポートされたメソッドを識別する手段として使用する。

しかし,Java Bean内部では,設計パタンに合うメソッド名及び型名を使用するのは, 完全にオプションとする。 プログラマが,インタフェースBeanInfoを使って,明示的に,その特性, メソッド及びイベントを指定する準備をすれば,それらが何であっても, そのメソッド及び型を呼び出すことができる。 しかし,これらのメソッド及び型は,それでも, 必要とされる型シグネチャに合致しなければならない。 これは,このことが,それら操作にとって本質的なことによる。

標準命名パタンの使用はオプションだが,これを標準命名規約として使用し, 極めて有益な文書化技術とすることが,非常に望ましい。
 

8.3 特性のための設計パタン

8.3.1 単純特性

デフォルトで,次の形式のメソッドを探すことによって, 特性を位置決めする設計パタンを使用する。

	public <Propertytype> get<PropertyName>(); 
	public void set<PropertyName>(<PropertyType> a);

同じ型を取り出し返却する,メソッド“get<PropertyName>” 及びメソッド“set<PropertyName>”の対応する対を発見する場合は, これらのメソッドを,<propertyName>という名前をもつ, 読取り書込み特性を定義するとみなす。 メソッド“get<PropertyName>”を使用して特性値を取得し, メソッド“set<PropertyName>”を使用して特性値を設定する。 メソッドの対は,同じクラスに置かれてもよいし,又は一方は基本クラスにあって, 他方は派生クラスにあってもよい。

これらメソッドの一つだけを見つけた場合は, <propertyName>と呼ぶ, 読取り専用特性又は書込み専用特性のいずれかを定義するとみなす。

デフォルトでは,特性は,束縛(bound) 特性でも 制約付き(constrained) 特性でもないと仮定する(7.参照)。

単純な読取り書込み特性“foo”は,次のメソッドの対で表現してよい。

	public Wombat getFoo(); 
	public void setFoo(Wombat w);
 

8.3.2 論理型特性

論理的特性に対しては,取得メソッドが,次のパタンと合致してよい。

	public boolean is<PropertyName>();

このメソッド“is<PropertyName>”は, メソッド“get<PropertyName>”の代わりに,又はメソッド “get<PropertyName>”に付加して,提供してよい。

いずれかの場合でも,メソッド“is<PropertyName>”が, 論理的特性に対して存在するときは,特性値を読み取るために, メソッド“is<PropertyName>”を使用する。

論理的特性の例を,次に示す。

	public boolean isMarsupial(); 
	public void setMarsupial(boolean m);
 

8.3.3 インデクス付き特性

型が,配列“<PropertyElement>[]” となる特性を発見する場合は,同様に,次の形式のメソッドを探す。

	public <PropertyElement> get<PropertyName>(int a);
	public void set<PropertyName>(int a, <PropertyElement> b);

いずれかの種類のパタンを発見すれば,“<propertyName>”が, インデクス付き特性であって,これらのメソッドを, インデクス付きの値の読取り及び/又は書込みのために使用できる,と仮定する。

そこで,インデクス付き特性“foo”は,次の四つのアクセサメソッドで, 表現されるかもしれない。

	public Bah[] getFoo(); 
	public void setFoo(Bah a []); 
	public Bah getFoo(int a); 
	public void setFoo(int a, Bah b);
 

8.4 イベントのための設計パタン

デフォルトで,ビーンが,どのイベントをマルチキャストするかを決定するために, 次の設計パタンを使用する。次の形式のメソッドの対を探す。

	public void add<EventListenerType>(<EventListenerType> a)
	public void remove<EventListenerType>(<EventListenerType> a)

この場合,両メソッドは,同じ型<EventListenerType>の実引数を取る。 ただし,型<EventListenerTypeは,インタフェース“java.util.EventListener” を拡張する。最初のメソッドは,“add”で始まり,2番目のメソッドは,“remove”で始まる。 型名“<EventListenerType>”は,“Listener”で終わる。

この設計パタンは,Java Beanが,インタフェース“<EventListenerType>” で指定するイベントのマルチキャストイベントソースとして動作していることを仮定する。

例えば,次の例は,マルチキャストイベントソースを定義する。

	public void addFredListener(FredListener t); 
	public void removeFredListener(FredListener t);
 

8.4.1 ユニキャストイベントソース

特別な場合として,これらの設計パタンを使用してイベントソースを位置決めする場合, メソッド“add<EventListenerType>”が, java.util.TooManyListenersException を投げるかどうかを検査する。 メソッド“add<EventListenerType>”が, java.util.TooManyListenerExceptionを投げれば,イベントソースは, ユニキャストであって,一度に登録されているイベントリスナは, 一つだけを許容すると仮定する。

例えば, 次の例は,インタフェース“JackListener” に対するユニキャストイベントソースを定義する。

	public void addJackListener(JackListener t) 
				throws java.util.TooManyListenersException; 
	public void removeJackListener(JackListener t);

 

8.5 メソッドのための設計パタン

デフォルトで,Java Beanのすべての公開メソッドは,部品環境内部での, 他の部品による又はスクリプト言語によるアクセスのために, 外部的メソッドとして開示することが望ましい,と仮定する。

デフォルトで,これには,あらゆる特性アクセサメソッド, あらゆるイベントリスナレジストリメソッドを含む。
 

8.6 クラスBeanInfoを使用する明示的な規定

Java Beanは,インタフェースBeanInfoを実装するクラスを提供することによって, どの特性,イベント及びメソッドをサポートするかを,明示的に指定することもできる。

インタフェースBeanInfoは,対象ビーンのイベント,特性, メソッド及び大域的な情報を知るためのメソッドを提供する。 ビーン配布の一部として,ISVも,ビーンのクラス名に“BeanInfo”を追加することで その名前を形成する,合致するクラスBeanInfoを配布する可能性がある。

Java Beansは,純粋にプログラム的なAPIを使用し, BeanInfo を通じて自己検査情報を取得する。 しかし,舞台の背後にある任意の私的なビーン記述ファイルを使用し, これらのファイルを読み取る方法を知るクラスBeanInfoを単に提供するだけという オプションを,個々の部品開発者はもつことに注意すること。

ビーンのクラスBeanInfoは,ビーンの振舞いの一部だけを指定する, 選択を行うかもしれない。それは,例えば,メソッド getEventSetDescriptors から配列 EventSetDescriptor を返し,ビーンのイベントに関する確実な情報を提供し, その一方で,メソッド getMethodDescriptors から null を返す方を選択するかもしれない。 これは,開示されたメソッドに関する情報を, ビーンそれ自体の調査によって発見することが望ましいことを示す。

そこで,ビーンの完全な図を得るために,アプリケーションツールは,常に, インタフェース Introspector(8.7を参照)を使用するのがよい。 インタフェース Introspector は,様々な潜在的なソースからの情報を組み合わせ, 対象ビーンに対応する確実な記述子BeanInfoを構成する。
 

8.7 Beanの分析

ビーンの開示された特性,メソッド及びイベントの明示的な規定 及び設計パタンを使用する暗黙的な分析の両方を許容する。

この情報へのアクセスを簡単にするために, 及びすべてのツールに確実に同じ分析規則を適用するために, クラスjava.beans.Introspectorを提供する。 これを,ビーンのクラスを分析するために使用することが望ましい。 クラスjava.beans.Introspectorを使用することで, 包括的に対象ビーンのクラスを記述するオブジェクトBeanInfoを得ることができる。

クラスInrospectorは,対象クラスのクラス及びスーパクラスの連鎖上を渡り歩く。 クラスIntrospectorは,各レベルで,ビーンについての明示的な情報を提供する, 合致するクラスBeanInfoが存在するかどうかを検査し,存在すれば, その明示的な情報を使用する。そうでなければ, 低レベルの自己反映APIを使用して対象クラスを調査し, 設計パタンを使用してその振舞いを分析し,それから, その基本クラスで自己検査を続行する。 (分析規則の完全な記述に関するクラスIntrospectorの定義を参照。)

この多重レベル分析は,ISVが, 明示的に指定した振舞いをする複雑なビーンの配布できるためとする。 その場合,これらのビーンズは,エンドカスタマによって,単純な方法で, サブクラス化され,拡張される。 エンドカスタマが付加した拡張を分析するために自動的な自己検査を使用し, 基本クラスを書いたISVによって提供される明示的な情報に追加を可能としたい。
 

8.8 推論された名前の大文字使用

設計パタンを使用して特性の名前又はイベントの名前を推論する場合, 推論された名前を大文字化するためには,どの規則に従うのがいいのかを, 決定する必要がある。通常,大文字小文字が混ざった様式の Java における名前の中央の辺りから名前を抽出すると,デフォルトでは, 名前は,大文字で始まることになる。

Javaのプログラマは,慣習的に,通常の識別子を小文字で始める。 この規定では,議論の結果,特性名及びイベント名に対しては, この同じ慣用規則に従うのがよい,とした。

そこで,既存のJavaにおける名前の中央の辺りから, 特性名及びイベント名が抽出する場合,通常, 最初の文字を小文字に変換する。 しかし,すべて大文字の名前を使用する場合をサポートするために, 名前の最初の2文字が両方とも大文字かどうか,及びその場合には, 両方とも大文字のままにしておくかどうかを検査する。 次に例を示す。

この変換規則を実装するメソッド Introspector.decapitalize を提供する。
 

8.9 セキュリティ

高レベルの自己検査 API だけが,対象ビーンの“公開” メソッドにおける情報を提供する。 通常の JDK セキュリティマネジャでは,信頼されないアプレットでも, java.lang.reflect API を使用して公開フィールド及び公開メソッドにアクセスできる。 しかし,私的なメソッド及び私的なフィールドへのアクセスは, “信頼される”アプリケーションビルダには適用されてもよいが, 信頼されないアプレットに対しては,通常は,拒絶される。
 

8.10 自己検査関連 API

8.10.1 クラス BeanDescriptor

public class java.beans.BeanDescriptor
  extends java.beans.FeatureDescriptor

BeanDescriptorは,そのJavaのクラス,そのdisplayName,などの, ビーンに関する大域的な情報を提供する。

これは,オブジェクトBeanInfoによって返される記述子の一種とする。 オブジェクトBeanInfoは,特性,メソッド及びイベントに対応する記述子も返す。

a) コンストラクタ

b) メソッド

 

8.10.2 インタフェース BeanInfo

public interface java.beans.BeanInfo

ビーンに関する明示的な情報を提供したいビーン実装者は, このインタフェースBeanInfoを実装し,ビーンのメソッド,特性,イベントなどについての, 明示的な情報を提供する,クラスBeanInfoを提供してもよい。

ビーン実装者は,明示的な情報の完全な集合を提供する必要はない。 どの情報を提供したいかを選択できる。 残りの情報は,ビーンクラスのメソッドの低レベル自己反映を使用し, 標準設計パタンを適用することで,自動分析によって取得する。

様々なクラスXyZDescriptorの一部として,極めて多様な情報を提供できる機会がある。 しかし,様々なコンストラクタが要求する,核となる最小限の情報だけが,本当に, 提供する必要がある。

クラスSimpleBeanInfoも参照すること。 クラスSimpleBeanInfoは,クラスBeanInfoに代わって,便利な“noop”基本クラスを提供し, 明示的な情報を返したい特定の個所のために,クラスBeanInfoを上書きできる。

ビーンの振舞いのすべてを知るためには,クラスIntrospectorを参照すること。
 

a) 変数

b) メソッド

8.10.3 クラス EventSetDescriptor

public class java.beans.EventSetDescriptor 
	extends java.beans.FeatureDescriptor

EventDescriptorは,与えられたJava Beanが起動するイベントのグループを示す。

イベントの与えられたグループは,すべて,単一のイベントリスナインタフェース上で, メソッド呼出しとして配布され,イベントリスナオブジェクトは,イベントソースによって, 提供される登録メソッドでの呼出しを介し,登録できる。

a) コンストラクタ

b) メソッド

 

8.10.4 クラス FeatureDescriptor

public class java.beans.FeatureDescriptor
	extends java.lang.Object

クラスFeatureDescriptorは,PropertyDescriptor,EventSetDescriptor 及び MethodDescriptor に対する共通した基本クラスとする。

クラスFeatureDescriptorは,すべての自己検査記述子に対して, 設定及び検索可能な共通情報をサポートする。

さらに,拡張機構を提供し,任意の属性及び値の対を, 設計特徴と関連付け可能にする。

a) コンストラクタ

b) メソッド

8.10.5 クラス IndexedPropertyDescriptor

public class java.beans.IndexedPropertyDescriptor 
	extends java.beans.PropertyDescriptor

IndexedPropertyDescriptor は,配列と同様に動作し, その配列の特定の要素にアクセスするために, インデクス付き読取りメソッド及び/又はインデクス付き書込みメソッドをもつ, 特性を示す。

インデクス付き特性は, 単純なインデクスなしの読取り及び書込みメソッドも提供するかもしれない。 これらが存在する場合は, インデクス付き読取りメソッドが返す型の配列の読取り及び書込みを行う。

a) コンストラクタ

b) メソッド

8.10.6 クラス IntrospectionException

public class java.beans.IntrospectionException 
	extends java.lang.Exception

自己検査中に例外が発生する場合に投げられる。

典型的な原因には,次がある。 つまり, 文字列のクラス名を Class オブジェクトに写像できない, 文字列のメソッド名を解決できない,又は 意図する使用とは違う型シグネチャをもつメソッド名を指定した。

a) コンストラクタ

8.10.7 クラス Introspector

public class java.beans.Introspector 
	extends java.lang.Object

クラス Introspector は,ツールが, 対象 Java Bean によってサポートされる特性, イベント及びメソッドについて知るための標準的な方法を提供する。

これら3種類の各情報に対し,Introspector は, 明示的な又は暗黙的な情報を探すために, ビーンのクラス及びスーパクラスを個々に分析し, その情報を使用して,対象ビーンを包括的に示す BeanInfo オブジェクトを構築する。

各クラス“Foo”に対し,対応するクラス"FooBeanInfo"が存在する場合, 明示的な情報が利用可能となる。クラス“FooBeanInfo”は, その情報が問い合わされたときに,nullでない値を提供する。 まず,対象ビーンクラスの完全パッケージ識別名を取り, これに“BeanInfo”を付加して新しいクラス名を作成することで, クラス BeanInfo を探す。 これが失敗した場合は,この名前の最後のクラス名の構成要素を取り出し, BeanInfo パッケージ探索経路内に指定された各パッケージ内で, そのクラスを探す。

そこで,“sun.xyz.OurButton”などのクラスに対しては, まず,“sun.xyz.OurButtonBeanInfo”と呼ぶクラス BeanInfo を探し, 失敗した場合は,クラス OurButtonBeanInfo の BeanInfo 探索経路内の各パッケージを見る。 これは,“sun.bean.infos.OurButtonBeanInfo”を, デフォルト探索経路で探すことを意味する。

クラスが,それ自体に関する明示的な BeanInfo を提供する場合, それを,派生クラスを分析して得た BeanInfo 情報に付加する。 しかし,その明示的な情報は,現クラス及びその基底クラスに限定するとみなし, スーパクラスの連鎖にまでは,続けない。

クラスについての明示的な BeanInfo が見つからない場合は, 低レベルの自己反映性を使用して,クラスのメソッドを調査し, 標準設計パターンを適用して,特性アクセサ,イベントソース又は 公開メソッドを識別する。 その上で,クラスのスーパクラスの分析を続行し, そのスーパクラス(及びスーパクラスの連鎖までという可能性もある) からの情報に付加する。

a) メソッド

8.10.8 クラス MethodDescriptor

public class java.beans.MethodDescriptor 
	extends java.beans.FeatureDescriptor

MethodDescriptor は,他の部品からの外部アクセスに対し, Java Beanがサポートする特定のメソッドを示す。

a) コンストラクタ

b) メソッド

8.10.9 クラス ParameterDescriptor

public class java.beans.ParameterDescriptor 
	extends java.beans.FeatureDescriptor

クラス ParameterDescriptor は,ビーンの実装者が, クラス java.lang.reflect.Method によって提供される低レベルの型情報以外の, 各パラメタの付加的情報を提供可能とする。

現在,すべての状態は,基底クラス FeatureDescriptor から生じる。

8.10.10 クラス PropertyDescriptor

public class java.beans.PropertyDescriptor 
	extends java.beans.FeatureDescriptor

PropertyDescriptor は,Java ビーンが, 一対のアクセサメソッドを介してエクスポートする一つの特性を示す。

a) コンストラクタ

b) メソッド

8.10.11 クラス SimpleBeanInfo

public class java.beans.SimpleBeanInfo 
	extends java.lang.Object 
	implements java.beans.BeanInfo

このクラスは,人が BeanInfo クラス群を提供するのを容易にする, サポートクラスとする。

このクラスは,デフォルトでは,“noop”情報を提供し, 選択した問題に関するより明示的な情報を提供するために,選択的に, 上書き可能とする。 “noop”値の場合は,自己検査は,低レベル自己検査及び設計パタンを適用して, 自動的に対象ビーンを分析する。

a) メソッド


目次 | |