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は、メッセージごとに新しいインスタンスを作成するか、readerPoolSize
FilterSettings
プロパティに従って、インスタンスをプールおよび再利用します。
リーダーは、現在のフィルタリングコンテキストの 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
リンクのコピー リンクがクリップボードにコピーされました!