Class VariableLengthDataRecordFormatter
- All Implemented Interfaces:
Closeable
,AutoCloseable
,DataRecordFormatter
本クラスはスレッドセーフを考慮した実装にはなっていないので、呼び出し元で同期化の制御を行うこと。
ディレクティブの設定可変長ファイルデータを読み込む際は、以下のディレクティブの設定が必須となる。
- ファイルの文字エンコーディング
- フィールド区切り文字(カンマ、タブなど)
- レコード終端文字列(\n、\r、\r\nなど)
また、任意で以下の設定を行うことができる。
- 囲み文字(デフォルトはダブルクォート)
- 最初の行をタイトルとして読み書きするかどうか
- 読み込みを許容する1行の文字列数(デフォルトは100万文字まで読み込み可能)
フィールド区切り文字および囲み文字は、任意の1文字を指定できる。
また、レコード終端文字列は、許容する文字列のみ指定できる。
デフォルトでは「\n」「\r」「\r\n」の3種類の文字列をレコード終端文字列として許容するが、
それを変更したい場合は、任意の許容する文字列のリストをFormatterFactory
クラスの allowedRecordSeparatorList プロパティに設定すること。
タイトル行の読み書き
requires-titleディレクティブにtrueを設定することで、タイトル行を読み書きする機能が有効となり、最初の行をタイトル行として通常のレコードタイプとは別に取り扱うことができるようになる。
この場合、最初の行はタイトル固定のレコードタイプ名[Title]で読み書きできるようになる。
(※ここでいうタイトルとは、ファイルの最初の行に存在し、個々のフィールドの論理名などが記載されるレコードのことを示す)
通常、タイトル行・データ行のような2つのレコードタイプが存在するファイルを読み込むためにはマルチフォーマットの定義を行う必要があるが、
タイトル行とデータ行に対してフォーマットの適用条件となるフィールドが存在しない場合、マルチフォーマットの定義では読み込むことができない。
しかし、本機能を使用すれば、最初の行はタイトル固有のレコードタイプが、最初の行以降はそれ以外のレコードタイプが適用されるので、
タイトル行とデータ行を識別するためのフィールドが存在しなくても、以下のとおりシングルフォーマットの定義で読み込むことができる。
requires-title: true # requires-titleがtrueの場合、最初の行をタイトルとして読み書きできる。 [Title] # タイトル固有のレコードタイプ。最初の行はこのレコードタイプで読み書きされる。 1 Kubun N 2 Name N 3 Publisher N 4 Authors N 5 Price N [DataRecord] # 最初の行以降の行はこのレコードタイプで読み書きされる。 1 Kubun X 2 Name N 3 Publisher N 4 Authors N 5 Price N
また、本機能を使用する場合、最初の行がタイトル行であることが保証されるので、ファイルレイアウトのバリデーションを省略できるといったメリットもある。
以上の点より、最初の行にタイトルが存在するファイルを読み込む場合は、本機能を使用することを推奨する。
最初の行をタイトルとして読み書きする場合、以下の制約が発生する。この制約を満たさない場合、例外がスローされるので注意すること。
- レコードタイプ [Title] を必ずフォーマット定義しなければならない。
- 最初の行を書き込む際に指定するレコードタイプは [Title] でなければならない。
- 最初の行以降を書き込む際に指定するレコードタイプは [Title] 以外でなければならない。
- レコードタイプ [Title] にフォーマットの適用条件が定義されている場合、読み書きする最初の行は必ずその適用条件を満たさなければならない。また、最初の行以降の行はその適用条件を満たしてはいけない。
タイトル固有のレコードタイプ名はデフォルトでは [Title] だが、title-record-type-name ディレクティブでタイトル固有のレコードタイプ名を個別に指定することも可能である。
-
Nested Class Summary
Modifier and TypeClassDescriptionstatic class
可変長ファイルフォーマッタが共通的に使用するディレクティブの名前と値の型。(タイプセーフEnum) 以下に一覧を示す。
field-separator:String quoting-delimiter:String ignore-blank-lines:Boolean requires-title:Boolean max-record-length:Integer title-record-type-name:StringNested classes/interfaces inherited from class nablarch.core.dataformat.DataRecordFormatterSupport
DataRecordFormatterSupport.Directive
-
Constructor Summary
ConstructorDescriptionデフォルトコンストラクタ。 デフォルトでは、VariableLengthConvertorSettingをコンバータとして使用する。 -
Method Summary
Modifier and TypeMethodDescriptionvoid
close()
内部的に保持している各種リソースを開放する。protected boolean
consumeQuoteIfExists
(Reader in, char quote) 後続の記号が囲み文字であれば読み込む。protected String
consumeSeparator
(Reader in, Character fieldSeparator, String recordSeparator) セパレータを読み込む。 セパレータが読み込めなければ実行時例外を送出する。protected Object
convertToField
(String fieldStr, FieldDefinition field) 読み込んだフィールド文字列をコンバータを用いてオブジェクトに変換し、返却する。protected DataRecord
convertToRecord
(List<String> fieldStrList, RecordDefinition recordDef) 読み込んだ1レコード分の文字列を、コンバータを用いてオブジェクトに変換し、返却する。protected Map<String,
DataRecordFormatterSupport.Directive> 使用するディレクティブの名前とDirectiveのMapを生成する。 サブクラスで使用するディレクティブを追加する場合は、本メソッドをオーバーライドし、任意のディレクティブを追加すること。protected boolean
endsWithChar
(Character character, StringBuilder buff) バッファの末尾が指定した1文字で終了しているのであれば、 その1文字をバッファから除去した上でtrueを返却する。protected boolean
endsWithString
(String str, StringBuilder buff) バッファの末尾が指定した文字列で終了しているのであれば、 その文字列をバッファから除去した上でtrueを返却する。protected VariableLengthConvertorSetting
コンバータの設定情報保持クラスを取得するboolean
hasNext()
次に読み込む行の有無を判定する。protected boolean
次に読み込む行があるかどうかを返却する。
空行の存在を無視する設定の場合、ファイル末尾に空行が存在しても、次に読み込む行がないと判定する。フォーマット定義情報保持クラスの初期化を行う。 初期化は本メソッドの1回目の実行時のみ行われ、2回目以降の実行時に初期化は行われない。protected void
initializeField
(Map<String, Object> directive) フィールドを初期化する。protected void
フィールド定義クラスについて、以下の初期化処理を行う。 コンバータ設定 エンコーディング設定 差分定義が行われている場合は、親のフィールド定義情報を反映 レコード長、フィールド長の妥当性検証protected void
フォーマット定義ファイルで指定されたエンコーディングで、可変長データを読み込むリーダを生成する。protected void
ライタを生成する。入力ストリームから1レコード分のデータを読み込み、データレコードを返却する。 入力ストリームが既に終端に達していた場合はnull
を返却する。入力ストリームから、1行分のレコードに存在するフィールドを、囲み文字などを取り除いた文字列のリストとして読み込む。protected DataRecordFormatterSupport
setDataTypeProperty
(DataType<?, ?> datatype) 空文字列をnull
に変換するかどうかを各データタイプに設定する。setInputStream
(InputStream stream) 入力ストリームを設定する。setOutputStream
(OutputStream stream) 出力ストリームを設定する。protected void
validateDirectives
(Map<String, Object> directive) ディレクティブの内容の妥当性を検証する。protected void
validateFieldLength
(List<String> fields, RecordDefinition recordDef) 1レコード分のフィールド数が正しいかどうか検証する。protected void
writeField
(Map<String, ?> record, FieldDefinition field) コンバータによる変換を行ったフィールドの内容を、出力ストリームへ書き込む。void
writeRecord
(String recordType, Map<String, ?> record) 指定したデータレイアウト(レコードタイプ)で、出力ストリームに1レコード分の内容を書き込む。void
writeRecord
(Map<String, ?> record) 出力ストリームに1レコード分の内容を書き込む。protected void
writeRecord
(Map<String, ?> record, RecordDefinition recordType) 1レコード分の内容を、出力ストリームへ書き込む。Methods inherited from class nablarch.core.dataformat.DataRecordFormatterSupport
addConvertorToField, addFormatAndRecordNumberTo, createCharacterReplacer, getDefaultEncoding, getDefinition, getFileType, getMimeType, getRecordNumber, getRecordSeparator, incrementRecordNumber, initializeClassifier, initializeDefinition, newInvalidDataFormatException, setAllowedRecordSeparatorList, setDefaultReplacementType, setDefinition, setFieldProperty, setRecordNumber, setValueConvertorProperty, validateDirectivesDataType, validatePosition, validateRecordLength
-
Constructor Details
-
VariableLengthDataRecordFormatter
デフォルトコンストラクタ。 デフォルトでは、VariableLengthConvertorSettingをコンバータとして使用する。
-
-
Method Details
-
initialize
フォーマット定義情報保持クラスの初期化を行う。 初期化は本メソッドの1回目の実行時のみ行われ、2回目以降の実行時に初期化は行われない。 また、入力ストリームをBufferedReaderにラップする処理および、 出力ストリームをBufferedWriterにラップする処理を行う。- Specified by:
initialize
in interfaceDataRecordFormatter
- Overrides:
initialize
in classDataRecordFormatterSupport
- Returns:
- このオブジェクト自体
-
createDirectiveMap
使用するディレクティブの名前とDirectiveのMapを生成する。 サブクラスで使用するディレクティブを追加する場合は、本メソッドをオーバーライドし、任意のディレクティブを追加すること。- Overrides:
createDirectiveMap
in classDataRecordFormatterSupport
- Returns:
- 使用するディレクティブの名前と値の型のMap
-
validateDirectives
ディレクティブの内容の妥当性を検証する。サブクラスで独自のディレクティブを使用する場合は、このメソッドをオーバーライドし、独自のディレクティブに対して妥当性検証を行うこと。
DataRecordFormatter
では以下の仕様を満たしているかどうかの検証を行う。- ディレクティブの値のデータ型が正しい
- ファイルタイプが定義されている
- エンコーディングが定義されている
- エンコーディングがCharset型に変換できる
- レコード終端文字列が許容されている文字である
妥当性検証に失敗した場合は、
SyntaxErrorException
がスローされる。- Overrides:
validateDirectives
in classDataRecordFormatterSupport
- Parameters:
directive
- ディレクティブ
-
initializeField
フィールドを初期化する。DataRecordFormatterSupport
では、ディレクティブに設定された以下の値をフィールドに設定する。- レコード終端文字列
- 文字エンコーディング
VariableLengthDataRecordFormatter
では、ディレクティブまたはコンポーネント設定ファイルに設定された以下の値をフィールドに設定する。- 囲み文字
- フィールド区切り文字
- 空行をスキップするかどうか
- 最初の行をタイトルとして読み書きするかどうか
- タイトルのレコードタイプ名
- 読み込みを許容する1行の文字列数
- タイトルのレコードタイプ名
- Overrides:
initializeField
in classDataRecordFormatterSupport
- Parameters:
directive
- ディレクティブ
-
initializeFieldDefinition
protected void initializeFieldDefinition()フィールド定義クラスについて、以下の初期化処理を行う。- コンバータ設定
- エンコーディング設定
- 差分定義が行われている場合は、親のフィールド定義情報を反映
- レコード長、フィールド長の妥当性検証
VariableLengthDataRecordFormatter
では、上記処理に加え、フォーマット定義が以下の条件を満たしているかどうかの検証を行う。条件を満たしていない場合、SyntaxErrorException
をスローする。- requires-titleディレクティブの値がtrueかつ、titleRecordTypeNameに設定されたレコードタイプ名と一致するレコードタイプがフォーマット定義されている。
- Overrides:
initializeFieldDefinition
in classDataRecordFormatterSupport
-
setInputStream
入力ストリームを設定する。- Parameters:
stream
- 入力ストリーム- Returns:
- 本クラスのインスタンス
-
setOutputStream
出力ストリームを設定する。- Parameters:
stream
- 出力ストリーム- Returns:
- 本クラスのインスタンス
-
readRecord
入力ストリームから1レコード分のデータを読み込み、データレコードを返却する。 入力ストリームが既に終端に達していた場合はnull
を返却する。- Returns:
- データレコード
- Throws:
IOException
- 入力ストリームの読み込みに失敗した場合
-
validateFieldLength
@Published(tag="architect") protected void validateFieldLength(List<String> fields, RecordDefinition recordDef) 1レコード分のフィールド数が正しいかどうか検証する。- Parameters:
fields
- フィールドのリストrecordDef
- レコード定義情報保持クラス
-
initializeReader
protected void initializeReader()フォーマット定義ファイルで指定されたエンコーディングで、可変長データを読み込むリーダを生成する。 -
convertToRecord
@Published(tag="architect") protected DataRecord convertToRecord(List<String> fieldStrList, RecordDefinition recordDef) throws IOException 読み込んだ1レコード分の文字列を、コンバータを用いてオブジェクトに変換し、返却する。- Parameters:
fieldStrList
- 読み込んだフィールド文字列のリストrecordDef
- レコード定義情報保持クラス- Returns:
- データレコード
- Throws:
IOException
- 読み込みに伴うIO処理で問題が発生した場合。
-
convertToField
読み込んだフィールド文字列をコンバータを用いてオブジェクトに変換し、返却する。- Parameters:
fieldStr
- 読み込んだフィールド文字列field
- フィールド定義情報保持クラス- Returns:
- コンバートしたフィールドの内容
-
writeRecord
出力ストリームに1レコード分の内容を書き込む。 出力時に使用するデータレイアウト(レコードタイプ)は、Map
の内容をもとに自動的に判定される。 引数がDataRecord
型かつレコードタイプが指定されている場合、 フォーマット定義ファイルのレコードタイプ識別フィールド定義よりも、指定されたレコードタイプを優先して書き込みを行う。- Parameters:
record
- 出力するレコードの内容を格納したMap- Throws:
IOException
- 出力ストリームの書き込みに失敗した場合InvalidDataFormatException
- 書き込むデータの内容がフォーマット定義に違反している場合
-
initializeWriter
protected void initializeWriter()ライタを生成する。 -
writeRecord
指定したデータレイアウト(レコードタイプ)で、出力ストリームに1レコード分の内容を書き込む。- Parameters:
recordType
- レコードタイプrecord
- 出力するレコードの内容を格納したMap- Throws:
IOException
- 出力ストリームの書き込みに失敗した場合
-
writeRecord
1レコード分の内容を、出力ストリームへ書き込む。- Parameters:
record
- 出力するレコードの内容を格納したMaprecordType
- レコードタイプ- Throws:
IOException
- 書き込みに伴うIO処理で問題が発生した場合。
-
writeField
コンバータによる変換を行ったフィールドの内容を、出力ストリームへ書き込む。- Parameters:
record
- 出力するレコードの内容を格納したMapfield
- フィールド定義情報保持クラス- Throws:
IOException
- 書き込みに伴うIO処理で問題が発生した場合
-
readRecordAsString
入力ストリームから、1行分のレコードに存在するフィールドを、囲み文字などを取り除いた文字列のリストとして読み込む。- Returns:
- 1行分のレコードを変換した文字列のリスト
- Throws:
IOException
- 読み込みに伴うIO処理で問題が発生した場合。
-
consumeQuoteIfExists
後続の記号が囲み文字であれば読み込む。- Parameters:
in
- 入力ストリームquote
- 囲み文字- Returns:
- 後続の記号が囲み文字であればtrue
- Throws:
IOException
- IOエラー
-
consumeSeparator
protected String consumeSeparator(Reader in, Character fieldSeparator, String recordSeparator) throws IOException セパレータを読み込む。 セパレータが読み込めなければ実行時例外を送出する。- Parameters:
in
- 入力ストリームrecordSeparator
- レコード終端文字列fieldSeparator
- フィールド区切り文字- Returns:
- 読み込んだ文字列
- Throws:
IOException
- IOエラー
-
endsWithString
バッファの末尾が指定した文字列で終了しているのであれば、 その文字列をバッファから除去した上でtrueを返却する。- Parameters:
str
- 終了条件の文字列buff
- バッファ- Returns:
- バッファの末尾が指定した文字列で終了しているのであればtrue
-
endsWithChar
バッファの末尾が指定した1文字で終了しているのであれば、 その1文字をバッファから除去した上でtrueを返却する。- Parameters:
character
- 1文字buff
- バッファ- Returns:
- バッファの末尾が指定した1文字で終了しているのであればtrue
-
hasNext
次に読み込む行の有無を判定する。 空行の存在を無視する設定の場合、ファイル末尾に空行が存在しても、次に読み込む行がないと判定する。- Returns:
- 次に読み込む行がある場合
true
- Throws:
IOException
- 入力ストリームの読み込みに失敗した場合
-
hasNextIgnoreBlankLines
次に読み込む行があるかどうかを返却する。
空行の存在を無視する設定の場合、ファイル末尾に空行が存在しても、次に読み込む行がないと判定する。- Returns:
- 次に読み込む行がある場合、true
- Throws:
IOException
- - IOエラー
-
close
public void close()内部的に保持している各種リソースを開放する。 この実装では、setInputStream(java.io.InputStream)
メソッドおよびsetOutputStream(java.io.OutputStream)
メソッドで渡されたストリーム、 および内部でそれらをラップするReader
、Writer
のストリームをクローズする。 -
getConvertorSetting
コンバータの設定情報保持クラスを取得する- Specified by:
getConvertorSetting
in classDataRecordFormatterSupport
- Returns:
- コンバータの設定情報保持クラス
-
setDataTypeProperty
空文字列をnull
に変換するかどうかを各データタイプに設定する。- Overrides:
setDataTypeProperty
in classDataRecordFormatterSupport
- Parameters:
datatype
- 対象のデータタイプ- Returns:
- このオブジェクト自体
-