セレクタは、ノードの接続関係やノード・オブジェクトのプロパティを条件にして、ノードを検索するためのAPIです。
セレクタを使用するには、最初に jp.carabiner.inkpod.pi.selector.Selector オブジェクトを構築します。
マップに含まれる全ノードから探す場合には、以下のようにします。
importPackage(Packages.jp.carabiner.inkpod.pi.selector); var s = new Selector(model.objectList)
(model変数は、PMapModelオブジェクトを指していると考えてください。)
選択中のマップ・オブジェクトから探す場合には、以下のようにします。
importPackage(Packages.jp.carabiner.inkpod.pi.selector); var s = new Selector(model.selectedObjects)
作ったばかりのセレクタには、与えたマップ・オブジェクトに含まれる全てのノードが含まれています。
セレクタの、select, next, previous, nextGraph, previousGraph メソッドは、セレクタに含まれているノード、または隣接するノードから条件にあったもののみを選択し、それらのノードを含む新しいセレクタを作って返します。
繰り返してこれらのメソッドを呼び出すことでノードを絞り込み、目的のノードのみを含むセレクタを得ることができます。
s = s.select(new PropertyEq("text", "foo", Condition.Target.SELF).select(...);
目的のノードのみを含むセレクタが得られたら、 getNode, getNodes, each, isEmpty メソッドを使って、含まれているノードを取り出したり、調べたりします。
s.each(function(index, node) { // node に対して処理 });
どの検索メソッドでも、引数に検索条件として、条件オブジェクトを渡します。
検索条件は、jp.carabiner.inkpod.pi.selector.Conditionインタフェースを実装したオブジェクトで表現されます。
それぞれの条件は、比較対象のマップ・オブジェクトを表す、列挙型jp.carabiner.inkpod.pi.selector.Condition.Target の値を持ちます。
Target.SELFは始点ノードのノード・オブジェクト、Target.NEXTは隣接するノードのノード・オブジェクト、Target.EDGEはその間の関連オブジェクトについての条件であることを表します。
関連の逆方向を調べるときは、次のように意味が入れ替わります。
条件オブジェクトについての詳細は、javadocのパッケージ jp.carabiner.inkpod.pi.selector のページを参照してください。
セレクタに含まれているノードを対象に検索します。
引数には、複数の条件を指定可能です。どれか1つの条件でも成立すればマッチします(OR条件)。
セレクタに含まれるノードと条件がマッチするかを調べ、条件にマッチしたノードを含む、新しいセレクタを返します。
セレクタに含まれているノードオブジェクトのみを条件判定の対象とします。よって、条件に比較対象として指定する列挙型Targetの値は、Target.SELFのみとなります。
それ以外を指定すると、jp.carabiner.inkpod.pi.selector.UnsupportedTargetException 例外が発生します。
セレクタに含まれているノードから、エッジの順方向に隣接しているノードを探すためのメソッドです。
引数には、複数の条件を指定可能です。どれか1つの条件でも成立すればマッチします(OR条件)。
セレクタに含まれているノードを始点ノードとして、始点ノード、エッジ、終点ノードの3つ組を作り、その単位で条件とマッチするか調べます。
3つ組のうち、どれとマッチさせるかは、各条件オブジェクトのCondition.Target列挙型の値で指定します。
条件にマッチした3つ組のうち、終点ノードを含む、新しいセレクタを返します。
next メソッドでは、始点ノードはセレクタに含まれているノードのみでしたが、それを関連線をたどった先のノードにも拡張したものです。
関連線を順方向にたどって到達可能な、全てのノードを検索対象にできます。
ただし、条件が成立しないノードより先は検索しません。
nextメソッドの、関連線の逆方向版です。
たどる方向が、関連線の逆方向である以外、next メソッドと同じです。
nextGraphメソッドの、関連線の逆方向版です。
たどる方向が、関連線の逆方向である以外、nextGraph メソッドと同じです。
Selector#select() メソッドのサンプルです。
select() は、Selectorオブジェクトに含まれるノードから、条件に合うノードを探します。
importPackage(Packages.jp.carabiner.inkpod.pi.selector); var s = new Selector(model.objectList) .select(new HasPreviousNode(0, Condition.Target.SELF)) .select(new HasNextNode(1, java.lang.Integer.MAX_VALUE, Condition.Target.SELF)); inkpod.showInfo(s.getCount());
(前後を省略しています)
このプログラムは、以下のようなマップがあったとき、まず、node1, node3, node5を探し、次にその中から、node1, node3を選び出し、最後にその数として2を表示します。
select() メソッドは、見つかったノードを含む新しいSelectorオブジェクトを返すので、次々とselect()メソッドを呼び出して、絞り込むことができます。
Selector#next() メソッドのサンプルです。
next() は、Selectorオブジェクトに含まれるノードからみて順方向に隣接するノードから、条件に合うノードを探します。
importPackage(Packages.jp.carabiner.inkpod.pi.selector); var s = new Selector(model.objectList) .select(new PropertyEq("text", "foo", Condition.Target.SELF)) .next(new PropertyEq("text", "bar", Condition.Target.NEXT)); frame.showInfo(s.getCount());
このプログラムは、以下のようなマップがあったとき、まず、foo(1) を探します。
次に、見つかったfoo(1) に順方向に隣接するノードから、textがbarというノードを探します。foo(1) と順方向に隣接するノードで、textがbarなのは、bar(2) と bar(3) なので、この2つを含んだ新しいセレクタが得られます。
最後に、見つかったノード数として、2を表示します。
Selector#nextGraph() のサンプルです。
nextGraph()は、セレクタに含まれるノードから、順方向に指定した条件が成立する限り次々とたどって、その全てを選択したセレクタを返します。
サンプル2との違いは、next() が、nextGraph() に変更されているだけです。
最終的に選択されるのは、bar(2), bar(3), bar(5) です。bar(6) は、間のbaz(4) で条件が成立しないため、それ以上たどられず、含まれません。
importPackage(Packages.jp.carabiner.inkpod.pi.selector); var s = new Selector(model.objectList) .select(new PropertyEq("text", "foo", Condition.Target.SELF)) .nextGraph(new PropertyEq("text", "bar", Condition.Target.NEXT)); frame.showInfo(s.getCount());
サンプル3に対して、bar(6) も探したい場合のサンプルです。
まず、nextGraph() を条件無しで呼び出すことで、foo(1) からつながる全てのノードを選択します。
それらのノードの中からtextがbarのノードを探します。
一度、nextGraph() でつながっているノードを全て集めてから探すことで、順方向で到達可能な範囲全てから探すことができます。
importPackage(Packages.jp.carabiner.inkpod.pi.selector); var s = new Selector(model.objectList) .select(new PropertyEq("text", "foo", Condition.Target.SELF)) .nextGraph() .select(new PropertyEq("text", "bar", Condition.Target.SELF)); frame.showInfo(s.getCount());