Smooks の主要な拡張ポイント/API は、リーダー API とビジター API です。
リーダー API
ソース/入力データ (リーダー) を処理して、すべてのメッセージフラグメントとサブフラグメントに明確に定義された一連の階層イベント (SAX イベントモデルに基づく) として他の Smooks コンポーネントによって消費できるようにするためのもの。
ビジター API
ソース/入力リーダーによって生成されたメッセージフラグメント SAX イベントを消費するためのもの。
リンクのコピー リンクがクリップボードにコピーされました!
すべての Smooks コンポーネントは、まったく同じ方法で設定されます。Smooks Core コードを使用する場合、すべての Smooks コンポーネントは、SmooksResourceConfiguration インスタンスを使用して設定された resources です。
リンクのコピー リンクがクリップボードにコピーされました!
リンクのコピー リンクがクリップボードにコピーされました!
<smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd">
<resource-config selector="">
<resource></resource>
<param name=""></param>
</resource-config>
</smooks-resource-list>
<smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd">
<resource-config selector="">
<resource></resource>
<param name=""></param>
</resource-config>
</smooks-resource-list>
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
selector 属性は、リソースを選択する機能です (たとえば、ビジター実装の XPath にすることができます)。
resource 要素は実際のリソースです。これは、Java クラス名またはテンプレートなどの他の形式のリソースにすることができます。このセクションの残りの部分では、リソースは Java クラス名であると想定されます。
param 要素は、resource 要素に定義されたリソースの設定パラメーターです。
リンクのコピー リンクがクリップボードにコピーされました!
Smooks は、リソースの実行時表現を作成するためのすべての詳細 (たとえば、リソース要素に指定されたクラスの構成) を処理し、すべての設定パラメーターを注入します。また、リソースタイプとは何か、およびそこからセレクターなどを解釈する方法も明らかにします。(たとえば、リソースがビジターインスタンスである場合は、ソースメッセージフラグメントを選択するセレクターが XPath であることを認識します。)
リンクのコピー リンクがクリップボードにコピーされました!
コンポーネントが作成されたら、<param> 要素の詳細を設定する必要があります。これは、@ConfigParam および @Config アノテーションを使用すると、実行されます。
リンクのコピー リンクがクリップボードにコピーされました!
@ConfigParam アノテーションは、アノテーション付きのプロパティ自身と同じ名前を持つ <param> 要素から名前付きパラメーターを反射的に注入します。名前は異なる場合がありますが、デフォルトの動作はコンポーネントプロパティーの名前に一致します。
リンクのコピー リンクがクリップボードにコピーされました!
このアノテーションにより、次の理由でコンポーネントから余分なコードが削除されます。
<param> 値をアノテーション付きのコンポーネントプロパティーに設定する前に、そのデコードを処理します。Smooks は、すべての主要な型 (int、Double、File、Enum など) に DataDecoder を提供しますが、すぐに使用できるデコーダーが特定のデコード要件をカバーしていない場合は、カスタム DataDecoder を実装および使用できます (例: @ConfigParam(decoder = MyQuirkyDataDecoder.class))。カスタムデコーダーが登録されている場合、Smooks はカスタムデコーダーを自動的に使用します (つまり、このアノテーションでデコーダープロパティーを定義する必要はありません)。Smooks が、特定のデータ型をデコードするために、DataDecoder 実装を自動的に見つけられるように、DataDecoder 実装を登録する方法の詳細については、DataDecoder Javadocs を参照してください。
config プロパティの choice 制約をサポートし、設定値が定義された選択値の 1 つではない場合、設定例外を生成します。たとえば、ON と OFF の制約付きの値セットを持つプロパティーがあるとします。このアノテーションの Choice プロパティーを使用して、設定を制約したり、例外を発生させたりすることができます。(たとえば、@ConfigParam(choice = {"ON", "OFF"}) です。)
@ConfigParam(defaultVal = "true") など、デフォルトの設定値を指定できます。
@ConfigParam(use = Use.OPTIONAL) など、プロパティー設定値が必須かオプションかを指定できます。デフォルトでは、すべてのプロパティーは、REQUIRED ですが、defaultVal を設定すると、プロパティーは、OPTIONAL と暗黙的にマークされます。
リンクのコピー リンクがクリップボードにコピーされました!
この例は、アノテーション付きのコンポーネント DataSeeder とそれに対応する Smooks 設定を示しています。
public class DataSeeder
{
@ConfigParam
private File seedDataFile;
public File getSeedDataFile()
{
return seedDataFile;
}
// etc...
}
public class DataSeeder
{
@ConfigParam
private File seedDataFile;
public File getSeedDataFile()
{
return seedDataFile;
}
// etc...
}
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
<smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd">
<resource-config selector="dataSeeder">
<resource>com.acme.DataSeeder</resource>
<param name="seedDataFile">./seedData.xml</param>
</resource-config>
</smooks-resource-list>
<smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd">
<resource-config selector="dataSeeder">
<resource>com.acme.DataSeeder</resource>
<param name="seedDataFile">./seedData.xml</param>
</resource-config>
</smooks-resource-list>
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
リンクのコピー リンクがクリップボードにコピーされました!
@Config アノテーションは、コンポーネントリソースに関連付けられた完全な SmooksResourceConfiguration インスタンスをアノテーション付きのコンポーネントプロパティに反射的に注入します。タイプ SmooksResourceConfiguration ではないコンポーネントプロパティーにこのアノテーションを追加すると、エラーが発生します。
リンクのコピー リンクがクリップボードにコピーされました!
public class MySmooksComponent
{
@Config
private SmooksResourceConfiguration config;
// etc...
public class MySmooksComponent
{
@Config
private SmooksResourceConfiguration config;
// etc...
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
リンクのコピー リンクがクリップボードにコピーされました!
場合によっては、コンポーネントに初期化コードを記述する必要がある複雑な設定が必要です。このために、Smooks は @Initialize アノテーションを提供しています。
同様に、関連する Smooks インスタンスが破棄される (ガベージコレクション) 際、初期化中に行った操作を元に戻す必要がある場合があります。たとえば、初期化中に取得したリソースを解放する場合などです。このために、Smooks は @Uninitialize アノテーションを提供しています。
リンクのコピー リンクがクリップボードにコピーされました!
これは、基本的な初期化/初期化解除シーケンスです。
smooks = new Smooks(..);
// Initialize all annotated components
@Initialize
// Use the smooks instance through a series of filterSource invocations...
smooks.filterSource(...);
smooks.filterSource(...);
smooks.filterSource(...);
... etc ...
smooks.close();
// Uninitialize all annotated components
@Uninitialize
smooks = new Smooks(..);
// Initialize all annotated components
@Initialize
// Use the smooks instance through a series of filterSource invocations...
smooks.filterSource(...);
smooks.filterSource(...);
smooks.filterSource(...);
... etc ...
smooks.close();
// Uninitialize all annotated components
@Uninitialize
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
リンクのコピー リンクがクリップボードにコピーされました!
public class MultiDataSourceAccessor
{
@ConfigParam
private File dataSourceConfig;
Map<String, Datasource> datasources = new HashMap<String, Datasource>();
@Initialize
public void createDataSources()
{
// Add DS creation code here....
// Read the dataSourceConfig property to read the DS configs...
}
@Uninitialize
public void releaseDataSources()
{
// Add DS release code here....
}
// etc...
}
public class MultiDataSourceAccessor
{
@ConfigParam
private File dataSourceConfig;
Map<String, Datasource> datasources = new HashMap<String, Datasource>();
@Initialize
public void createDataSources()
{
// Add DS creation code here....
// Read the dataSourceConfig property to read the DS configs...
}
@Uninitialize
public void releaseDataSources()
{
// Add DS release code here....
}
// etc...
}
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
上記の @Initialize および @Uninitialize アノテーションを使用する場合は、次の点に注意する必要があります。
@Initialize および @Uninitialize メソッドは、引数なしのパブリックメソッドである必要があります。
@ConfigParam プロパティーは、最初の @Initialize メソッドが呼び出される前に、すべて初期化されます。したがって、@ConfigParam コンポーネントプロパティーを初期化プロセスへの入力として使用できます。
@Uninitialize メソッドは、すべて Smooks.close メソッドの呼び出しに応答して、呼び出されます。
リンクのコピー リンクがクリップボードにコピーされました!
Smooks は、コンポーネントのカスタム設定 namespace を定義する機能をサポートしています。これにより、<resource-config> 基本設定を使用して、検証可能なコンポーネントの XSD ベースのカスタム設定をすべて一般的な Smooks リソースとして扱うのではなく、サポートできます。
リンクのコピー リンクがクリップボードにコピーされました!
基本的なプロセスには、次の 2 つの手順が含まれます。
カスタム namespace 設定を SmooksResourceConfiguration インスタンスにマッピングする Smooks 設定 namespace マッピング設定ファイルを記述します。このファイルは、マッピングする namespace の名前に基づいて (慣例により)、名前を付ける必要があり、XSD と同じフォルダー内のクラスパスに物理的に配置する必要があります。上記の例を拡張すると、Smooks マッピングファイルは、/META-INF/schemas/smooks/acme-core-1.0.xsd-smooks.xml になります。-smooks.xml 接尾辞に注意してください。
この機能に慣れるための最も簡単な方法は、Smooks コード自体の既存の拡張 namespace 設定を確認することです。すべての Smooks コンポーネント (Java バインド機能を含む) は、この機能を使用して、設定を定義します。Smooks Core 自体は、多くの拡張設定 namespace を定義します。
リンクのコピー リンクがクリップボードにコピーされました!
カスタムデータ形式のソースリーダーを実装すると、Java バインド、テンプレート、保持、検証、分割、ルーティングなど、そのデータ形式に対するすべての Smooks 機能をすぐに開くことができます。Smooks の唯一の要件は、リーダーが、Java JDK からの標準の org.xml.sax.XMLReader インターフェイスを実装していることです。ただし、リーダー実装を設定できるようにする場合は、リーダーが、org.milyn.xml.SmooksXMLReader インターフェースを実装する必要があります。org.milyn.xml.SmooksXMLReader は org.xml.sax.XMLReader の拡張です。既存の org.xml.sax.XMLReader 実装を使用することも、新しいものを実装することも簡単です。
リンクのコピー リンクがクリップボードにコピーされました!
次のように、まず、基本的なリーダークラスを実装する必要があります。
public class MyCSVReader implements SmooksXMLReader
{
// Implement all of the XMLReader methods...
}
public class MyCSVReader implements SmooksXMLReader
{
// Implement all of the XMLReader methods...
}
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
特に興味深いものは、org.xml.sax.XMLReader インターフェイスの 2 つのメソッドです。
setContentHandler(ContentHandler) は Smooks Core によって呼び出されます。リーダーの org.xml.sax.ContentHandler インスタンスを設定します。org.xml.sax.ContentHandler インスタンスメソッドは、parse(InputSource) メソッド内から呼び出されます。
parse(InputSource): これは、ソースデータ入力ストリームを受け取り、解析し (つまり、この例の場合は、CSVストリーム)、setContentHandler(ContentHandler) メソッドで提供される org.xml.sax.ContentHandler インスタンスの呼び出しで SAX イベントストリームを生成するメソッドです。
CSV レコードに関連付けられたフィールドの名前を使用して、CSV リーダーを設定します。カスタムリーダー実装の設定は、いずれの Smooks コンポーネントでも同じです。以下の例を参照してください。
public class MyCSVReader implements SmooksXMLReader
{
private ContentHandler contentHandler;
@ConfigParam
private String[] fields; // Auto decoded and injected from the "fields" <param> on the reader config.
public void setContentHandler(ContentHandler contentHandler) {
this.contentHandler = contentHandler;
}
public void parse(InputSource csvInputSource) throws IOException, SAXException {
// TODO: Implement parsing of CSV Stream...
}
// Other XMLReader methods...
}
public class MyCSVReader implements SmooksXMLReader
{
private ContentHandler contentHandler;
@ConfigParam
private String[] fields; // Auto decoded and injected from the "fields" <param> on the reader config.
public void setContentHandler(ContentHandler contentHandler) {
this.contentHandler = contentHandler;
}
public void parse(InputSource csvInputSource) throws IOException, SAXException {
// TODO: Implement parsing of CSV Stream...
}
// Other XMLReader methods...
}
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
基本的なリーダー実装スタブができると、単体テストの作成を開始して、新しいリーダー実装をテストできます。これを行うには、CSV 入力が必要です。names.csv という名前のファイル内の名前の単純なリストを特徴とする以下の例を確認してください。
Tom,Jones
Mike,Jones
Mark,Jones
Tom,Jones
Mike,Jones
Mark,Jones
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
テスト Smooks 設定を使用して、MyCSVReader で Smooks を設定します。前述のとおり、Smooks では、すべてがリソースであり、基本的な <resource-config> 設定を行うことができます。これは、問題なく動作しますが、少し「うるさい」ため、Smooks は、特にリーダーを設定するために、基本的な <reader> 設定要素を提供しています。テストの設定は、mycsvread-config.xml で次のようになります。
<smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd">
<reader class="com.acme.MyCSVReader">
<params>
<param name="fields">firstname,lastname</param>
</params>
</reader>
</smooks-resource-list>
<smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd">
<reader class="com.acme.MyCSVReader">
<params>
<param name="fields">firstname,lastname</param>
</params>
</reader>
</smooks-resource-list>
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
JUnit テストクラスを実装します。
public class MyCSVReaderTest extends TestCase
{
public void test() {
Smooks smooks = new Smooks(getClass().getResourceAsStream("mycsvread-config.xml"));
StringResult serializedCSVEvents = new StringResult();
smooks.filterSource(new StreamSource(getClass().getResourceAsStream("names.csv")), serializedCSVEvents);
System.out.println(serializedCSVEvents);
// TODO: add assertions etc
}
}
public class MyCSVReaderTest extends TestCase
{
public void test() {
Smooks smooks = new Smooks(getClass().getResourceAsStream("mycsvread-config.xml"));
StringResult serializedCSVEvents = new StringResult();
smooks.filterSource(new StreamSource(getClass().getResourceAsStream("names.csv")), serializedCSVEvents);
System.out.println(serializedCSVEvents);
// TODO: add assertions etc
}
}
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
parse メソッドを実装します。
public class MyCSVReader implements SmooksXMLReader
{
private ContentHandler contentHandler;
@ConfigParam
private String[] fields; // Auto decoded and injected from the "fields" <param> on the reader config.
public void setContentHandler(ContentHandler contentHandler)
{
this.contentHandler = contentHandler;
}
public void parse(InputSource csvInputSource) throws IOException, SAXException
{
BufferedReader csvRecordReader = new BufferedReader(csvInputSource.getCharacterStream());
String csvRecord;
// Send the start of message events to the handler...
contentHandler.startDocument();
contentHandler.startElement(XMLConstants.NULL_NS_URI, "message-root", "", new AttributesImpl());
csvRecord = csvRecordReader.readLine();
while(csvRecord != null)
{
String[] fieldValues = csvRecord.split(",");
// perform checks...
// Send the events for this record...
contentHandler.startElement(XMLConstants.NULL_NS_URI, "record", "", new AttributesImpl());
for(int i = 0; i < fields.length; i++)
{
contentHandler.startElement(XMLConstants.NULL_NS_URI, fields[i], "", new AttributesImpl());
contentHandler.characters(fieldValues[i].toCharArray(), 0, fieldValues[i].length());
contentHandler.endElement(XMLConstants.NULL_NS_URI, fields[i], "");
}
contentHandler.endElement(XMLConstants.NULL_NS_URI, "record", "");
csvRecord = csvRecordReader.readLine();
}
// Send the end of message events to the handler...
contentHandler.endElement(XMLConstants.NULL_NS_URI, "message-root", "");
contentHandler.endDocument();
}
// Other XMLReader methods...
}
public class MyCSVReader implements SmooksXMLReader
{
private ContentHandler contentHandler;
@ConfigParam
private String[] fields; // Auto decoded and injected from the "fields" <param> on the reader config.
public void setContentHandler(ContentHandler contentHandler)
{
this.contentHandler = contentHandler;
}
public void parse(InputSource csvInputSource) throws IOException, SAXException
{
BufferedReader csvRecordReader = new BufferedReader(csvInputSource.getCharacterStream());
String csvRecord;
// Send the start of message events to the handler...
contentHandler.startDocument();
contentHandler.startElement(XMLConstants.NULL_NS_URI, "message-root", "", new AttributesImpl());
csvRecord = csvRecordReader.readLine();
while(csvRecord != null)
{
String[] fieldValues = csvRecord.split(",");
// perform checks...
// Send the events for this record...
contentHandler.startElement(XMLConstants.NULL_NS_URI, "record", "", new AttributesImpl());
for(int i = 0; i < fields.length; i++)
{
contentHandler.startElement(XMLConstants.NULL_NS_URI, fields[i], "", new AttributesImpl());
contentHandler.characters(fieldValues[i].toCharArray(), 0, fieldValues[i].length());
contentHandler.endElement(XMLConstants.NULL_NS_URI, fields[i], "");
}
contentHandler.endElement(XMLConstants.NULL_NS_URI, "record", "");
csvRecord = csvRecordReader.readLine();
}
// Send the end of message events to the handler...
contentHandler.endElement(XMLConstants.NULL_NS_URI, "message-root", "");
contentHandler.endDocument();
}
// Other XMLReader methods...
}
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
単体テストクラスを実行して、コンソールに次の出力を表示します (フォーマット済み)。
<message-root>
<record>
<firstname>Tom</firstname>
<lastname>Jones</lastname>
</record>
<record>
<firstname>Mike</firstname>
<lastname>Jones</lastname>
</record>
<record>
<firstname>Mark</firstname>
<lastname>Jones</lastname>
</record>
</message-root>
<message-root>
<record>
<firstname>Tom</firstname>
<lastname>Jones</lastname>
</record>
<record>
<firstname>Mike</firstname>
<lastname>Jones</lastname>
</record>
<record>
<firstname>Mark</firstname>
<lastname>Jones</lastname>
</record>
</message-root>
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
この後は、テストの拡張、リーダー実装コードの強化などのケースです。その後、リーダーを使用して、Smooks でサポートされているさまざまな操作を実行できます。
リンクのコピー リンクがクリップボードにコピーされました!
次の設定 (java-binding-config.xml) を使用すると、名前を PersonName オブジェクトのList にバインドできます。
<smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd" xmlns:jb="http://www.milyn.org/xsd/smooks/javabean-1.4.xsd">
<reader class="com.acme.MyCSVReader">
<params>
<param name="fields">firstname,lastname</param>
</params>
</reader>
<jb:bean beanId="peopleNames" class="java.util.ArrayList" createOnElement="message-root">
<jb:wiring beanIdRef="personName" />
</jb:bean>
<jb:bean beanId="personName" class="com.acme.PersonName" createOnElement="message-root/record">
<jb:value property="first" data="record/firstname" />
<jb:value property="last" data="record/lastname" />
</jb:bean>
</smooks-resource-list>
<smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd" xmlns:jb="http://www.milyn.org/xsd/smooks/javabean-1.4.xsd">
<reader class="com.acme.MyCSVReader">
<params>
<param name="fields">firstname,lastname</param>
</params>
</reader>
<jb:bean beanId="peopleNames" class="java.util.ArrayList" createOnElement="message-root">
<jb:wiring beanIdRef="personName" />
</jb:bean>
<jb:bean beanId="personName" class="com.acme.PersonName" createOnElement="message-root/record">
<jb:value property="first" data="record/firstname" />
<jb:value property="last" data="record/lastname" />
</jb:bean>
</smooks-resource-list>
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
その設定のテストは次のとおりです。
public class MyCSVReaderTest extends TestCase
{
public void test_java_binding()
{
Smooks smooks = new Smooks(getClass().getResourceAsStream("java-binding-config.xml"));
JavaResult javaResult = new JavaResult();
smooks.filterSource(new StreamSource(getClass().getResourceAsStream("names.csv")), javaResult);
List<PersonName> peopleNames = (List<PersonName>) javaResult.getBean("peopleNames");
// TODO: add assertions etc
}
}
public class MyCSVReaderTest extends TestCase
{
public void test_java_binding()
{
Smooks smooks = new Smooks(getClass().getResourceAsStream("java-binding-config.xml"));
JavaResult javaResult = new JavaResult();
smooks.filterSource(new StreamSource(getClass().getResourceAsStream("names.csv")), javaResult);
List<PersonName> peopleNames = (List<PersonName>) javaResult.getBean("peopleNames");
// TODO: add assertions etc
}
}
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
リンクのコピー リンクがクリップボードにコピーされました!
リーダーインスタンスが同時に使用されることはありません。Smooks Coreは、メッセージごとに新しいインスタンスを作成するか、readerPoolSizeFilterSettings プロパティに従って、インスタンスをプールおよび再利用します。
リーダーは、現在のフィルタリングコンテキストの Smooks ExecutionContext にアクセスする必要がある場合、org.milyn.xml.SmooksXMLReader インターフェイスを実装する必要があります。
ソースデータがバイナリーデータストリームである場合、リーダーは、org.milyn.delivery.StreamReader インターフェイスを実装する必要があります。
GenericReaderConfigurator インスタンスを使用して、ソースコード (単体テストなど) 内でリーダーを設定し、Smooks インスタンスに設定できます。
基本的な <reader> 設定は問題ありませんが、カスタム CSV リーダー実装用にカスタム設定 namespace (XSD) を定義できます。このトピックは、ここでは扱いません。ソースコードを確認して、Smooks に付属するリーダー実装の拡張設定 namespace (EDIReader、CSVReader、JSONReader など) を確認します。これから、独自のカスタムリーダーでこれを行う方法を考え出すことができるはずです。
リンクのコピー リンクがクリップボードにコピーされました!
バイナリーソースリーダー はバイナリーデータソースのリーダーです。リーダーは、org.milyn.delivery.StreamReader インターフェイスを実装する必要があります。これは、InputStream が提供されるように、Smooks ランタイムに指示する単なるマーカーインターフェイスです。
バイナリーリーダーの実装は、非バイナリーリーダーの実装 (上記を参照) と本質的に同じですが、parse メソッドの実装が、InputSource からのInputStream を使用し (つまり、InputSource.getCharacterStream() ではなく、InputSource..getByteStream() を呼び出し)、デコードされたバイナリーデータから XML イベントを生成する必要がある点では異なります。
リンクのコピー リンクがクリップボードにコピーされました!
バイナリーソースリーダーを実装するには、次の parse メソッド実装を確認してください。
public static class BinaryFormatXXReader implements SmooksXMLReader, StreamReader
{
@ConfigParam
private String xProtocolVersion;
@ConfigParam
private int someOtherXProtocolConfig;
// etc...
public void parse(InputSource inputSource) throws IOException, SAXException {
// Use the InputStream (binary) on the InputSource...
InputStream binStream = inputSource.getByteStream();
// Create and configure the data decoder...
BinaryFormatXDecoder xDecoder = new BinaryFormatXDecoder();
xDecoder.setProtocolVersion(xProtocolVersion);
xDecoder.setSomeOtherXProtocolConfig(someOtherXProtocolConfig);
xDecoder.setXSource(binStream);
// Generate the XML Events on the contentHandler...
contentHandler.startDocument();
// Use xDecoder to fire startElement, endElement etc events on the contentHandler (see previous section)...
contentHandler.endDocument();
}
// etc....
}
public static class BinaryFormatXXReader implements SmooksXMLReader, StreamReader
{
@ConfigParam
private String xProtocolVersion;
@ConfigParam
private int someOtherXProtocolConfig;
// etc...
public void parse(InputSource inputSource) throws IOException, SAXException {
// Use the InputStream (binary) on the InputSource...
InputStream binStream = inputSource.getByteStream();
// Create and configure the data decoder...
BinaryFormatXDecoder xDecoder = new BinaryFormatXDecoder();
xDecoder.setProtocolVersion(xProtocolVersion);
xDecoder.setSomeOtherXProtocolConfig(someOtherXProtocolConfig);
xDecoder.setXSource(binStream);
// Generate the XML Events on the contentHandler...
contentHandler.startDocument();
// Use xDecoder to fire startElement, endElement etc events on the contentHandler (see previous section)...
contentHandler.endDocument();
}
// etc....
}
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
他のリーダーと同様、Smooks 設定に BinaryFormatXXReader リーダーを設定します。
<smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd">
<reader class="com.acme.BinaryFormatXXReader">
<params>
<param name="xProtocolVersion">2.5.7</param>
<param name="someOtherXProtocolConfig">1</param>
... etc...
</params>
</reader>
... Other Smooks configurations e.g. <jb:bean> configs for binding the binary data into Java objects...
</smooks-resource-list>
<smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd">
<reader class="com.acme.BinaryFormatXXReader">
<params>
<param name="xProtocolVersion">2.5.7</param>
<param name="someOtherXProtocolConfig">1</param>
... etc...
</params>
</reader>
... Other Smooks configurations e.g. <jb:bean> configs for binding the binary data into Java objects...
</smooks-resource-list>
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
Smooks の実行コードを実行します (StreamSource に提供される InputStream に注意してください)。この場合、XML オブジェクトと Java オブジェクトの 2 つの結果が生成されます。
StreamResult xmlResult = new StreamResult(xmlOutWriter);
JavaResult javaResult = new JavaResult();
InputStream xBinaryInputStream = getXByteStream();
smooks.filterSource(new StreamSource(xBinaryInputStream), xmlResult, javaResult);
// etc... Use the beans in the javaResult...
StreamResult xmlResult = new StreamResult(xmlOutWriter);
JavaResult javaResult = new JavaResult();
InputStream xBinaryInputStream = getXByteStream();
smooks.filterSource(new StreamSource(xBinaryInputStream), xmlResult, javaResult);
// etc... Use the beans in the javaResult...
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
リンクのコピー リンクがクリップボードにコピーされました!
ビジター実装 は、Smooks の主要な機能です。Smooks のすぐに使える機能 (Java バインド、テンプレート、保持など) のほとんどは、1 つ以上のビジター実装を使用して、作成されました。ビジター実装は、多くの場合、ExecutionContext および ApplicationContext コンテキストオブジェクトでコラボレーションして、共通の目標を達成します。
リンクのコピー リンクがクリップボードにコピーされました!
org.milyn.delivery.sax.SAXVisitor サブインターフェイスに基づく SAX ベースの実装。
org.milyn.delivery.dom.DOMVisitor サブインターフェイスに基づく DOM ベースの実装。
リンクのコピー リンクがクリップボードにコピーされました!
実装は SAX と DOM の両方をサポートできますが、Red Hat は SAX のみのビジターを実装することを推奨します。通常、SAX ベースの実装は作成が簡単であり、実行も高速です。
すべてのビジター実装は、ステートレスオブジェクトとして扱われます。1 つのビジターインスタンスは、複数のメッセージ、つまり Smooks.filterSource メソッドの複数の同時呼び出しで同時に使用できる必要があります。現在の Smooks.filterSource 実行に関連するすべての状態は、ExecutionContext に保存する必要があります。
リンクのコピー リンクがクリップボードにコピーされました!
SAX ビジター API は多くのインターフェイスで構成されています。これらのインターフェイスは、SAXVisitor 実装が取得および処理できる org.xml.sax.ContentHandler SAX イベントに基づいています。SAXVisitor 実装によって解決されるユースケースに応じて、これらのインターフェイスの 1 つまたはすべてを実装する必要がある場合があります。
リンクのコピー リンクがクリップボードにコピーされました!
org.milyn.delivery.sax.SAXVisitBefore
対象のフラグメント要素の startElement SAX イベントを取得します。
public interface SAXVisitBefore extends SAXVisitor
{
void visitBefore(SAXElement element, ExecutionContext executionContext)
throws SmooksException, IOException;
}
public interface SAXVisitBefore extends SAXVisitor
{
void visitBefore(SAXElement element, ExecutionContext executionContext)
throws SmooksException, IOException;
}
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
org.milyn.delivery.sax.SAXVisitChildren
対象のフラグメント要素の文字ベースの SAX イベント、および子フラグメント要素の startElement イベントに対応する Smooks 生成 (疑似) イベントを取得します。
public interface SAXVisitChildren extends SAXVisitor
{
void onChildText(SAXElement element, SAXText childText, ExecutionContext
executionContext) throws SmooksException, IOException;
void onChildElement(SAXElement element, SAXElement childElement,
ExecutionContext executionContext) throws SmooksException, IOException;
}
public interface SAXVisitChildren extends SAXVisitor
{
void onChildText(SAXElement element, SAXText childText, ExecutionContext
executionContext) throws SmooksException, IOException;
void onChildElement(SAXElement element, SAXElement childElement,
ExecutionContext executionContext) throws SmooksException, IOException;
}
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
org.milyn.delivery.sax.SAXVisitAfter
対象のフラグメント要素の endElement SAX イベントを取得します。
public interface SAXVisitAfter extends SAXVisitor
{
void visitAfter(SAXElement element, ExecutionContext executionContext)
throws SmooksException, IOException;
}
public interface SAXVisitAfter extends SAXVisitor
{
void visitAfter(SAXElement element, ExecutionContext executionContext)
throws SmooksException, IOException;
}
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
リンクのコピー リンクがクリップボードにコピーされました!
<message>
<target-fragment> <!-- SAXVisitBefore.visitBefore -->
Text!! <!-- SAXVisitChildren.onChildText -->
<child> <!-- SAXVisitChildren.onChildElement -->
</child>
</target-fragment> <!-- SAXVisitAfter.visitAfter -->
</message>
<message>
<target-fragment> <!-- SAXVisitBefore.visitBefore -->
Text!! <!-- SAXVisitChildren.onChildText -->
<child> <!-- SAXVisitChildren.onChildElement -->
</child>
</target-fragment> <!-- SAXVisitAfter.visitAfter -->
</message>
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
上記は、XML としてのソースメッセージイベントストリームの図です。EDI、CSV、JSON、またはその他の形式の可能性があります。これは、読みやすいように、XML としてシリアル化されたソースメッセージイベントストリームであると考えてください。
上記の SAX インターフェイスからわかるように、org.milyn.delivery.sax.SAXElement タイプは、すべてのメソッド呼び出しで渡されます。このオブジェクトには、属性とその値を含む、対象のフラグメント要素に関する詳細が含まれています。また、テキストの蓄積を管理するためのメソッド、および Smooks.filterSource(Source, Result) メソッド呼び出しで渡された可能性がある StreamResult インスタンスに関連する Writer へのアクセスが含まれています。
リンクのコピー リンクがクリップボードにコピーされました!
SAX はストリームベースの処理モデルです。ドキュメントオブジェクトモデル (DOM) を作成したり、イベントデータを蓄積したりすることはありません。これが、巨大なメッセージストリームの処理に適した処理モデルである理由です。
リンクのコピー リンクがクリップボードにコピーされました!
org.milyn.delivery.sax.SAXElement は、常に対象の要素に関連する属性データを含みますが、フラグメントの子テキストデータを含みません。SAX イベント (SAXVisitChildren.onChildText) が SAXVisitBefore.visitBefore イベントと SAXVisitAfter.visitAfter イベントの間に発生します。テキストイベントは、SAXElement に蓄積されません。その結果、パフォーマンスが大幅に低下する可能性があるためです。この欠点は、SAXVisitor 実装がフラグメントのテキストコンテンツにアクセスする必要がある場合、対象のフラグメントのテキストを蓄積するように、Smooks に明示的に指示する必要があることです。これは、SAXVisitor の SAXVisitBefore.visitBefore メソッド実装内から SAXElement.accumulateText メソッドを呼び出すと、実行されます。
リンクのコピー リンクがクリップボードにコピーされました!
public class MyVisitor implements SAXVisitBefore, SAXVisitAfter
{
public void visitBefore(SAXElement element, ExecutionContext executionContext)
throws SmooksException, IOException
{
element.accumulateText();
}
public void visitAfter(SAXElement element, ExecutionContext executionContext)
throws SmooksException, IOException
{
String fragmentText = element.getTextContent();
// ... etc ...
}
}
public class MyVisitor implements SAXVisitBefore, SAXVisitAfter
{
public void visitBefore(SAXElement element, ExecutionContext executionContext)
throws SmooksException, IOException
{
element.accumulateText();
}
public void visitAfter(SAXElement element, ExecutionContext executionContext)
throws SmooksException, IOException
{
String fragmentText = element.getTextContent();
// ... etc ...
}
}
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
リンクのコピー リンクがクリップボードにコピーされました!
@TextConsumer アノテーションは、SAXVisitBefore.visitBefore メソッドを使用する代わりに、SAXVisitor 実装をアノテーションするために、使用することができます。
リンクのコピー リンクがクリップボードにコピーされました!
@TextConsumer
public class MyVisitor implements SAXVisitAfter
{
public void visitAfter(SAXElement element, ExecutionContext executionContext)
throws SmooksException, IOException
{
String fragmentText = element.getTextContent();
// ... etc ...
}
}
@TextConsumer
public class MyVisitor implements SAXVisitAfter
{
public void visitAfter(SAXElement element, ExecutionContext executionContext)
throws SmooksException, IOException
{
String fragmentText = element.getTextContent();
// ... etc ...
}
}
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
フラグメントテキストの全容は、SAXVisitAfter.visitAfter イベントの終了後、公開されます。
リンクのコピー リンクがクリップボードにコピーされました!
デフォルトでは、Smooks は常に完全なソースイベントストリームを XML として、Smooks.filterSource(Source, Result) メソッドに提供される任意の StreamResult インスタンスにシリアル化します。Smooks.filterSource(Source, Result) メソッドに提供されたソースが XML ストリームであり、StreamResult インスタンスが Result インスタンスの 1 つとして提供された場合は、Smooks インスタンスが 1 つ以上のフラグメントを変更する 1 つ以上の SAXVisitor 実装で設定されていないかぎり、ソース XML は未変更の StreamResult に書き出されます。
リンクのコピー リンクがクリップボードにコピーされました!
デフォルトのシリアル化動作をオンまたはオフにするには、フィルター設定にアクセスし、そのように設定します。
メッセージフラグメントの 1 つのシリアル化された形式を変更するには、SAXVisitor を実装して、変換を実行し、XPath のような式を使用して、メッセージフラグメントをターゲットとします。
メッセージフラグメントのシリアル化された形式を変更するには、提供されているテンプレートコンポーネントのいずれかを使用します。これらのコンポーネントは、SAXVisitor 実装でもあります。
リンクのコピー リンクがクリップボードにコピーされました!
フラグメントのシリアル化された形式を変換するための SAXVisitor を実装するには、SAXVisitor 実装が StreamResult に書き込まれるように、Smooks をプログラミングします。これは、Smooks が 1 つのフラグメントで複数の SAXVisitor 実装のターゲティングをサポートしているためですが、フラグメントごとに StreamResult に書き込むことができる SAXVisitor は、1 つだけです。
2 つ目の SAXVisitor が StreamResult に書き込もうとすると、SAXWriterAccessException が発生し、Smooks 設定を変更する必要があります。
記述する StreamResult を指定するには、SAXVisitor が、StreamResult への Writer の所有権を取得する必要があります。これは、SAXVisitBefore.visitBefore メソッド実装内から、SAXElement.getWriter(SAXVisitor) メソッドを呼び出し、this を SAXVisitor パラメーターとして渡すと、実行されます。
リンクのコピー リンクがクリップボードにコピーされました!
public class MyVisitor implements SAXElementVisitor
{
public void visitBefore(SAXElement element, ExecutionContext executionContext)
throws SmooksException, IOException
{
Writer writer = element.getWriter(this);
// ... write the start of the fragment...
}
public void onChildText(SAXElement element, SAXText childText,
ExecutionContext executionContext)
throws SmooksException, IOException
{
Writer writer = element.getWriter(this);
// ... write the child text...
}
public void onChildElement(SAXElement element, SAXElement childElement,
ExecutionContext executionContext)
throws SmooksException, IOException
{
}
public void visitAfter(SAXElement element, ExecutionContext executionContext)
throws SmooksException, IOException
{
Writer writer = element.getWriter(this);
// ... close the fragment...
}
}
public class MyVisitor implements SAXElementVisitor
{
public void visitBefore(SAXElement element, ExecutionContext executionContext)
throws SmooksException, IOException
{
Writer writer = element.getWriter(this);
// ... write the start of the fragment...
}
public void onChildText(SAXElement element, SAXText childText,
ExecutionContext executionContext)
throws SmooksException, IOException
{
Writer writer = element.getWriter(this);
// ... write the child text...
}
public void onChildElement(SAXElement element, SAXElement childElement,
ExecutionContext executionContext)
throws SmooksException, IOException
{
}
public void visitAfter(SAXElement element, ExecutionContext executionContext)
throws SmooksException, IOException
{
Writer writer = element.getWriter(this);
// ... close the fragment...
}
}
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
リンクのコピー リンクがクリップボードにコピーされました!
SAXElement.setWriter を使用すると、Writer インスタンスをリセットするために必要なサブフラグメントのシリアル化を制御できるため、サブフラグメントのシリアル化を流用できます。
シリアル化/変換しているターゲットフラグメントにサブフラグメントがまったくないことがわかっている場合があります。この状況では、Writer の所有権を獲得するための SAXElement.getWriter メソッドを呼び出すためだけに、SAXVisitBefore.visitBefore メソッドを実装することは非効率的です。このため、@StreamResultWriter アノテーションがあります。@TextConsumer アノテーションと組み合わせて使用すると、SAXVisitAfter.visitAfter メソッドを実装するだけで十分です。
リンクのコピー リンクがクリップボードにコピーされました!
@StreamResultWriter
public class MyVisitor implements SAXVisitAfter
{
public void visitAfter(SAXElement element, ExecutionContext executionContext)
throws SmooksException, IOException
{
Writer writer = element.getWriter(this);
// ... serialize to the writer ...
}
}
@StreamResultWriter
public class MyVisitor implements SAXVisitAfter
{
public void visitAfter(SAXElement element, ExecutionContext executionContext)
throws SmooksException, IOException
{
Writer writer = element.getWriter(this);
// ... serialize to the writer ...
}
}
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
リンクのコピー リンクがクリップボードにコピーされました!
Smooks は、SAXToXMLWriter クラスを提供します。SAXElement データを XML としてシリアル化するプロセスを簡素化します。このクラスでは、SAXVisitor 実装を記述できます。
リンクのコピー リンクがクリップボードにコピーされました!
@StreamResultWriter
public class MyVisitor implements SAXElementVisitor
{
private SAXToXMLWriter xmlWriter = new SAXToXMLWriter(this, true);
public void visitBefore(SAXElement element, ExecutionContext executionContext)
throws SmooksException, IOException
{
xmlWriter.writeStartElement(element);
}
public void onChildText(SAXElement element, SAXText childText, ExecutionContext
executionContext) throws SmooksException, IOException
{
xmlWriter.writeText(childText, element);
}
public void onChildElement(SAXElement element, SAXElement childElement,
ExecutionContext executionContext) throws SmooksException, IOException
{
}
public void visitAfter(SAXElement element, ExecutionContext executionContext)
throws SmooksException, IOException
{
xmlWriter.writeEndElement(element);
}
}
@StreamResultWriter
public class MyVisitor implements SAXElementVisitor
{
private SAXToXMLWriter xmlWriter = new SAXToXMLWriter(this, true);
public void visitBefore(SAXElement element, ExecutionContext executionContext)
throws SmooksException, IOException
{
xmlWriter.writeStartElement(element);
}
public void onChildText(SAXElement element, SAXText childText, ExecutionContext
executionContext) throws SmooksException, IOException
{
xmlWriter.writeText(childText, element);
}
public void onChildElement(SAXElement element, SAXElement childElement,
ExecutionContext executionContext) throws SmooksException, IOException
{
}
public void visitAfter(SAXElement element, ExecutionContext executionContext)
throws SmooksException, IOException
{
xmlWriter.writeEndElement(element);
}
}
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
リンクのコピー リンクがクリップボードにコピーされました!
SAXToXMLWriter で SAXVisitor 実装を記述する場合は、SAXToXMLWriter コンストラクターにブール値を設定します。encodeSpecialChars argであり、rewriteEntities フィルター設定に基づいて、設定する必要があります。
@StreamResultWriter アノテーションをクラスから SAXToXMLWriter インスタンス宣言に移動します。この結果、Smooks は、SAXToXMLWriter インスタンスを作成し、関連する Smooks インスタンスの rewriteEntities フィルター設定で初期化されます。
@TextConsumer
public class MyVisitor implements SAXVisitAfter
{
@StreamResultWriter
private SAXToXMLWriter xmlWriter;
public void visitAfter(SAXElement element, ExecutionContext executionContext)
throws SmooksException, IOException
{
xmlWriter.writeStartElement(element);
xmlWriter.writeText(element);
xmlWriter.writeEndElement(element);
}
}
@TextConsumer
public class MyVisitor implements SAXVisitAfter
{
@StreamResultWriter
private SAXToXMLWriter xmlWriter;
public void visitAfter(SAXElement element, ExecutionContext executionContext)
throws SmooksException, IOException
{
xmlWriter.writeStartElement(element);
xmlWriter.writeText(element);
xmlWriter.writeEndElement(element);
}
}
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
リンクのコピー リンクがクリップボードにコピーされました!
SAXVisitor 設定は、テスト目的に役立ち、他の Smooks コンポーネントとまったく同様に機能します。Smooks ビジターインスタンスを設定する場合は、設定 selector は、XPath 式と同様に解釈されます。ビジターインスタンスは、Smooks インスタンスのプログラムコード内で設定できます。
リンクのコピー リンクがクリップボードにコピーされました!
この例では、次のような SAXVisitor 実装を使用します。
@TextConsumer
public class ChangeItemState implements SAXVisitAfter
{
@StreamResultWriter
private SAXToXMLWriter xmlWriter;
@ConfigParam
private String newState;
public void visitAfter(SAXElement element, ExecutionContext executionContext)
throws SmooksException, IOException
{
element.setAttribute("state", newState);
xmlWriter.writeStartElement(element);
xmlWriter.writeText(element);
xmlWriter.writeEndElement(element);
}
}
@TextConsumer
public class ChangeItemState implements SAXVisitAfter
{
@StreamResultWriter
private SAXToXMLWriter xmlWriter;
@ConfigParam
private String newState;
public void visitAfter(SAXElement element, ExecutionContext executionContext)
throws SmooksException, IOException
{
element.setAttribute("state", newState);
xmlWriter.writeStartElement(element);
xmlWriter.writeText(element);
xmlWriter.writeEndElement(element);
}
}
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
ステータスが OK の<order-item> フラグメントをトリガーするように、ChangeItemState を宣言的に設定すると、次のようになります。
<smooks-resource-list
xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd">
<resource-config selector="order-items/order-item[@status = 'OK']">
<resource>com.acme.ChangeItemState </resource>
<param name="newState">COMPLETED</param>
</resource-config>
</smooks-resource-list>
<smooks-resource-list
xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd">
<resource-config selector="order-items/order-item[@status = 'OK']">
<resource>com.acme.ChangeItemState </resource>
<param name="newState">COMPLETED</param>
</resource-config>
</smooks-resource-list>
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
カスタム設定 namespace を使用すると、よりクリーンな厳密に型指定された設定を ChangeItemState コンポーネントに定義できます。カスタム設定 namespace コンポーネントは次のように設定されます。
<smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd"
xmlns:order="http://www.acme.com/schemas/smooks/order.xsd">
<order:changeItemState itemElement="order-items/order-item[@status = 'OK']"
newState="COMPLETED" />
</smooks-resource-list>
<smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd"
xmlns:order="http://www.acme.com/schemas/smooks/order.xsd">
<order:changeItemState itemElement="order-items/order-item[@status = 'OK']"
newState="COMPLETED" />
</smooks-resource-list>
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
このビジターは、次のように、ソースコードに設定することもできます。
Smooks smooks = new Smooks();
smooks.addVisitor(new ChangeItemState().setNewState("COMPLETED"),
"order-items/order-item[@status = 'OK']");
smooks.filterSource(new StreamSource(inReader), new StreamResult(outWriter));
Smooks smooks = new Smooks();
smooks.addVisitor(new ChangeItemState().setNewState("COMPLETED"),
"order-items/order-item[@status = 'OK']");
smooks.filterSource(new StreamSource(inReader), new StreamResult(outWriter));
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
リンクのコピー リンクがクリップボードにコピーされました!
ExecutionLifecycleCleanable ライフサイクルインターフェイスを実装するビジターコンポーネントはポスト Smooks.filterSource ライフサイクル操作を実行できます。以下の例を参照してください。
public interface ExecutionLifecycleCleanable extends Visitor
{
public abstract void executeExecutionLifecycleCleanup(
ExecutionContext executionContext);
}
public interface ExecutionLifecycleCleanable extends Visitor
{
public abstract void executeExecutionLifecycleCleanup(
ExecutionContext executionContext);
}
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
基本的な呼び出しシーケンスは、次のように記述できます (executeExecutionLifecycleCleanup 呼び出しに注意)。
smooks = new Smooks(..);
smooks.filterSource(...);
// ** VisitorXX.executeExecutionLifecycleCleanup **
smooks.filterSource(...);
// ** VisitorXX.executeExecutionLifecycleCleanup **
smooks.filterSource(...);
// ** VisitorXX.executeExecutionLifecycleCleanup **
... etc ...
smooks = new Smooks(..);
smooks.filterSource(...);
// ** VisitorXX.executeExecutionLifecycleCleanup **
smooks.filterSource(...);
// ** VisitorXX.executeExecutionLifecycleCleanup **
smooks.filterSource(...);
// ** VisitorXX.executeExecutionLifecycleCleanup **
... etc ...
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
このライフサイクルメソッドでは、Smooks.filterSource 実行ライフサイクルの周囲にスコープされたリソースを関連する ExecutionContext のためにクリーンアップできます。
リンクのコピー リンクがクリップボードにコピーされました!
VisitLifecycleCleanable ライフサイクルインターフェイスを実装するビジターコンポーネントはポスト SAXVisitAfter.visitAfter ライフサイクル操作を実行できます。
public interface VisitLifecycleCleanable extends Visitor
{
public abstract void executeVisitLifecycleCleanup(ExecutionContext executionContext);
}
public interface VisitLifecycleCleanable extends Visitor
{
public abstract void executeVisitLifecycleCleanup(ExecutionContext executionContext);
}
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
基本的な呼び出しシーケンスは、次のように記述できます (executeVisitLifecycleCleanup 呼び出しに注意)。
smooks.filterSource(...);
<message>
<target-fragment> < --- VisitorXX.visitBefore
Text!! < --- VisitorXX.onChildText
<child> < --- VisitorXX.onChildElement
</child>
</target-fragment> < --- VisitorXX.visitAfter
** VisitorXX.executeVisitLifecycleCleanup **
<target-fragment> < --- VisitorXX.visitBefore
Text!! < --- VisitorXX.onChildText
<child> < --- VisitorXX.onChildElement
</child>
</target-fragment> < --- VisitorXX.visitAfter
** VisitorXX.executeVisitLifecycleCleanup **
</message>
VisitorXX.executeExecutionLifecycleCleanup
smooks.filterSource(...);
<message>
<target-fragment> < --- VisitorXX.visitBefore
Text!! < --- VisitorXX.onChildText
<child> < --- VisitorXX.onChildElement
</child>
</target-fragment> < --- VisitorXX.visitAfter
** VisitorXX.executeVisitLifecycleCleanup **
<target-fragment> < --- VisitorXX.visitBefore
Text!! < --- VisitorXX.onChildText
<child> < --- VisitorXX.onChildElement
</child>
</target-fragment> < --- VisitorXX.visitAfter
** VisitorXX.executeVisitLifecycleCleanup **
</message>
VisitorXX.executeExecutionLifecycleCleanup
smooks.filterSource(...);
<message>
<target-fragment> < --- VisitorXX.visitBefore
Text!! < --- VisitorXX.onChildText
<child> < --- VisitorXX.onChildElement
</child>
</target-fragment> < --- VisitorXX.visitAfter
** VisitorXX.executeVisitLifecycleCleanup **
<target-fragment> < --- VisitorXX.visitBefore
Text!! < --- VisitorXX.onChildText
<child> < --- VisitorXX.onChildElement
</child>
</target-fragment> < --- VisitorXX.visitAfter
** VisitorXX.executeVisitLifecycleCleanup **
</message>
VisitorXX.executeExecutionLifecycleCleanup
smooks.filterSource(...);
<message>
<target-fragment> < --- VisitorXX.visitBefore
Text!! < --- VisitorXX.onChildText
<child> < --- VisitorXX.onChildElement
</child>
</target-fragment> < --- VisitorXX.visitAfter
** VisitorXX.executeVisitLifecycleCleanup **
<target-fragment> < --- VisitorXX.visitBefore
Text!! < --- VisitorXX.onChildText
<child> < --- VisitorXX.onChildElement
</child>
</target-fragment> < --- VisitorXX.visitAfter
** VisitorXX.executeVisitLifecycleCleanup **
</message>
VisitorXX.executeExecutionLifecycleCleanup
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
このライフサイクルメソッドでは、SAXVisitor 実装の 1 つのフラグメント実行の周囲にスコープされたリソースを関連する ExecutionContext のためにクリーンアップできます。
リンクのコピー リンクがクリップボードにコピーされました!
ExecutionContext は状態情報を保存するためのコンテキストオブジェクトです。Smooks.filterSource メソッドの 1 回の実行に特化して、スコープされています。すべての Smooks ビジター実装は、1 つの Smooks.filterSource 実行のコンテキスト内でステートレスである必要があり、ビジター実装を Smooks.filterSource メソッドの複数の同時実行で使用できるようにします。ExecutionContext インスタンスに保存されているすべてのデータは、Smooks.filterSource 実行の完了時、失われます。ExecutionContext は、すべてのビジター API メッセージイベント呼び出しで提供されます。
リンクのコピー リンクがクリップボードにコピーされました!
ApplicationContext は状態情報を保存するためのコンテキストオブジェクトです。関連する Smooks インスタンスの周囲にスコープされます。つまり、1 つの Smooks インスタンスにつき、1 つの ApplicationContext インスタンスのみが存在します。このコンテキストオブジェクトは、複数の Smooks.filterSource 実行で維持およびアクセスする必要があるデータを保存するために、使用できます。コンポーネント (SAXVisitor コンポーネントを含む) は、ApplicationContext クラスプロパティを宣言し、@AppContext アノテーションを付けて、関連する ApplicationContext インスタンスにアクセスできます。以下の例を参照してください。
public class MySmooksComponent
{
@AppContext
private ApplicationContext appContext;
// etc...
}
public class MySmooksComponent
{
@AppContext
private ApplicationContext appContext;
// etc...
}
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
リンクのコピー リンクがクリップボードにコピーされました!