Lombokで生成したメソッドをJavaDocに反映する方法
Lombok を公開するライブラリとして使用したとき、デフォルトではJavaDocに反映されないため、その手順を紹介します。
大まかな手順としては、Delombok により静的なソースを生成し、そのソースに対してJavaDocを作成するというものです。
Delombokとは?
Lombokによりコンパイル時にAST(Abstract Syntax Tree: 抽象構文木)の構造を動的に変更します。
Delombokはその逆で、動的にメソッドなどを追加するのではなく静的に変更したソースを出力する機能です。
pom.xmlの設定
Delombokのプラグインを追加します。
JavaDocのプラグインには、
それぞれ、テスト用ソースに対しても設定します。
<project> <build> <plugins> <!-- Delombokによるソースを出力します --> <plugin> <groupId>org.projectlombok</groupId> <artifactId>lombok-maven-plugin</artifactId> <version>1.18.12.0</version> <executions> <!-- 通常のソースに対して生成します --> <execution> <id>delombok</id> <phase>generate-sources</phase> <goals> <goal>delombok</goal> </goals> <configuration> <addOutputDirectory>false</addOutputDirectory> <sourceDirectory>src/main/java</sourceDirectory> <encoding>${source.encode}</encoding> </configuration> </execution> <!-- テスト用ソースに対して生成します --> <execution> <id>test-delombok</id> <phase>generate-test-sources</phase> <goals> <goal>testDelombok</goal> </goals> <configuration> <addOutputDirectory>false</addOutputDirectory> <sourceDirectory>src/test/java</sourceDirectory> <encoding>${source.encode}</encoding> </configuration> </execution> </executions> </plugin> </plugins> </build> <reporting> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-javadoc-plugin</artifactId> <version>3.2.0</version> <reportSets> <!-- Delombokにより生成したソースに対してJavaDocを生成します --> <reportSet> <id>html</id> <configuration> <sourcepath>target/generated-sources/delombok</sourcepath> </configuration> <reports> <report>javadoc</report> </reports> </reportSet> <reportSet> <id>test-html</id> <configuration> <show>private</show> <sourcepath>target/generated-test-sources/delombok</sourcepath> </configuration> <reports> <report>test-javadoc</report> </reports> </reportSet> </reportSets> </plugin> </plugins> </reporting> </project>
Delombokを使う際の注意事項
Delombokによる生成されたソースについて注意事項として、無駄な空行が入ってしまったり、逆に空行がなくなったっりします。
JavaDocを生成する差には空行は関係ないので気にはしなくてもよいと思います。
Delombok前のソース
package com.github.mygreen.sqltemplate; import lombok.Getter; import lombok.NonNull; /** * SQLテンプレートのパラメータをJavaBean として渡すときのSQLコンテキスト。 * SQLテンプレート中では、JavaBeanのプロパティ名で参照できます。 * * */ public class BeanPropertySqlContext extends SqlContext { /** * JavaBeanのインスタンス。 */ @Getter private final Object value; }
Delombokにより生成したソース
// Generated by delombok at Sun Jul 26 23:32:11 JST 2020 package com.github.mygreen.sqltemplate; /** * SQLテンプレートのパラメータをJavaBean として渡すときのSQLコンテキスト。 * SQLテンプレート中では、JavaBeanのプロパティ名で参照できます。 * * */ public class BeanPropertySqlContext extends SqlContext { /** * JavaBeanのインスタンス。 */ private final Object value; /** * JavaBeanを指定するコンストラクタ。 * @param object SQLテンプレート中のパラメータとして渡すJavaBeanのインスタンス */ public BeanPropertySqlContext(@NonNull final Object object) { super(); if (object == null) { throw new java.lang.NullPointerException("object is marked non-null but is null"); } this.value = object; } /** * JavaBeanのインスタンス。 */ @java.lang.SuppressWarnings("all") @lombok.Generated public Object getValue() { return this.value; } }
SceneBuilder 11で日本語が文字化けする事象の修正方法
SceneBuilder11のインストーラ形式を入れて、起動するとメニューなどが文字化けする。
ver10のときから直っていないので、11用の直し方を説明する。
1.アプリ本体「scenebuilder-11.0.0-all.jar」の取得
SceneBuilder11からインストール個所を選択できなくなり、インストール個所は「C:\Program Files\SceneBuilder\all」と固定となった。
Program Files以下だと権限の都合上エラーとなるため、「scenebuilder-11.0.0-all.jar」を作業用のディレクトリ「c:\temp」以下にコピーする。
2.コマンドプロンプトで以下を実行し、元のjarをバックアップする。
> copy scenebuilder-11.0.0-all.jar scenebuilder-11.0.0-all.jar.org
3.プロパティファイル「SceneBuilderApp_ja.properties」を抽出する。
※Java SDKにパスを通しておく必要がある。
> %JAVA_HOME%\bin\jar xvf scenebuilder-11.0.0-all.jar com/oracle/javafx/scenebuilder/app/i18n/SceneBuilderApp_ja.properties
4.文字化けしていないプロパティファイルをGitHubから取得して、抽出したファイルに上書きする。
※プロパティファイル「SceneBuilderApp_ja.properties」は、UTF-8で保存する。
- 文字化けしていないダウンロードするプロパティファイル
- ダウンロードしたファイルを格納するフォルダ
C:\temp\com\oracle\javafx\scenebuilder\app\i18n\
5.ダウンロードしたプロパティファイルをjarに取り込む。
> %JAVA_HOME%\bin\jar uf scenebuilder-11.0.0-all.jar com/oracle/javafx/scenebuilder/app/i18n/SceneBuilderApp_ja.properties
6.更新した「scenebuilder-11.0.0-all.jar」を元のインストールした箇所にコピーする。
C:\Program Files\SceneBuilder\app\scenebuilder-11.0.0-all.jar
7.SceneBuilderを起動してみると、無事文字化けが治っていることが確認できます。
SceneBuilder 10で日本語が文字化けする事象の修正方法
SceneBuilderのインストーラ形式を入れて、起動するとメニューなどが文字化けする。
対処方法として知られているのが、メニューを英語で表示し対応するというもの。
qiita.com
だけど、やっぱし、日本語を正しく表示したい。ということで、調査結果とその対応方法を紹介します。
【文字化けしたメニュー】
なぜ文字化けするのか?
まず、SceneBuilder本体のjarの中身を見てみます。
「<インストールフォルダ>\SceneBuilder\app\dist.jar」 が本体です。
jarを解凍してできた中身の「com/oracle/javafx/scenebuilder/app/i18n/SceneBuilderApp_ja.properties」が画面などのプロパティファイルになります。
マルチバイトはASCIIコードに変換されているので当然だよね。
# ----------------------------------------------------------------------------- # Generic labels # ----------------------------------------------------------------------------- label.ok = OK label.cancel = \u00e5\ufffd\u2013\u00e6\u00b6\u02c6 label.close = \u00e9\u2013\u2030\u00e3\ufffd\u02dc\u00e3\u201a\u2039 label.delete = \u00e5\u2030\u0160\u00e9\u2122\u00a4 label.copy = \u00e3\u201a\u00b3\u00e3\u0192\u201d\u00e3\u0192\u00bc
と思い、プロパティエディタで開いてみると、文字化けしていた。これが原因ですね。
修正方法
元のファイルをリポジトリからとってきてとか面倒なので、「Executable Jar」版からプロパティファイルを抽出し、入れ変えて試します。
1. まず、Executable Jarである「scenebuilder-10.0.0-all.jar」をSceneBuilderのサイトからダウンロードしてきます。
2.ダウンロードしてきたファイル「scenebuilder-10.0.0-all.jar」を、SceneBuilderのインストールしたフォルダの「SceneBuilder/app/dist.jar」と同じディレクトリに配置します。
3. コマンドプロンプトで以下を実行し、jarからプロパティファイルを抽出し、dist.jarに取り込みます。
dist.jarが存在するフォルダに移動します。(環境によって異なります)
> C:\Java\SceneBuilder\app
dist.jarをコピーして、バックアップします。
> copy dist.jar dist.jar.org
scenebuilder-10.0.0-all.jarから、プロパティファイル「SceneBuilderApp_ja.properties」を抽出します。
> jar xvf scenebuilder-10.0.0-all.jar com/oracle/javafx/scenebuilder/app/i18n/SceneBuilderApp_ja.properties
抽出したプロパティファイル「SceneBuilderApp_ja.properties」をdist.jarに取り込みます。
> jar uf dist.jar com/oracle/javafx/scenebuilder/app/i18n/SceneBuilderApp_ja.properties
さあ、これでSceneBuilderを起動してみましょう。
メニューなどが正しく日本語で表示されましたね。
さあ、良いJavaFXライフを!!
XlsMapper 2.0リリース
遂に、やっと、XlsMepper 2.0がリリースできました。
v1.6のリリースから約1年半かかりました。
その間、転職したり、色々とあり、遅々として作業が進まず、なんども萎えました。
v1.6 ⇒ v2.0 とメジャーバージョンが上がったことによる影響は大きいです。
互換性がなくなったアノテーションは多々あります。
詳細は、リリースノートを参照してください。
16. リリースノート — XlsMapper 2.0 ドキュメント
概要
- 前提として、Java8になります。
- Java9/10は未確認のため後日確認します。
- 前提として、最新版のPOI-3.17のみをサポートします。
- POIの以前のバージョンは未サポートとなります。
- 新しいマッピング用のアノテーションとして、@XlsArrayCells/@XlsLabelledArrayCells が追加になっています。
- 書き込み時の設定を別アノテーションとして分離しました。
- @XlsHorizontalRecords(overRecord=..., remainedRecord=...) を、@XlsRecordOption で指定するようにしました。
- 一部のクラス名など変更になっています。例. XlsConfig ⇒ Configuration。
詳細
後日追加。
Super CSV Annotation v2.1のリリース
最近、処理速度が速いと言われていた univocity-parsers に対して、Super CSV Annotationがカラム番号を指定しないでラベル名でマッピングできないとかという記事を見たので、Super Csv Annotation v2.1 として、機能追加してリリースした。
あと、univocity-parsersは固定長のカラムもできるので、その機能も追加した。
詳細は、マニュアルを参照。
固定長カラムの対応
固定長のカラムとは、「書き込み時は任意の長さになるよう空白などを詰め、読み込み時は書き込み時に詰めた空白などの文字を除去する」ことだと定義して、それを実現する変換用のアノテーションを合成したアノテーション @CsvFixedSize を付与します。
- 属性sizeで固定長のサイズを指定します。
- 属性rightAlignで、右寄せするかどうか指定します。falseの場合は左寄席せになります。
- 属性padCharで、パディングする文字を指定することができます。
- デフォルトは半角空白で、全角空白なども指定できます。
ヘッダーもカラムの設定と同様に固定長にするには、@CsvBean(headerMapper=FixedSizeHeaderMapper.class) と指定します。
import com.github.mygreen.supercsv.annotation.CsvBean; import com.github.mygreen.supercsv.annotation.CsvColumn; import com.github.mygreen.supercsv.annotation.CsvFixedSize; import com.github.mygreen.supercsv.builder.FixedSizeHeaderMapper; // ヘッダーも固定長にするには、「headerMapper=FixedSizeHeaderMapper.class」を指定します。 @CsvBean(header=true, headerMapper=FixedSizeHeaderMapper.class) public class SampleCsv { // 右詰めする @CsvColumn(number=1) @CsvFixedSize(size=10, rightAlign=true) private int id; // パディング文字を全角空白にする。 // 全角を入力する前提としたカラムと想定し、さらに @CsvFullChar で半角を全角に変換します。 @CsvColumn(number=2, label="氏名") @CsvFixedSize(size=20, padChar=' ') @CsvFullChar private String name; // パディング文字をアンダースコア(_)にする。 @CsvColumn(number=3, label="生年月日") @CsvFixedSize(length=10, padChar='_') @CsvDateTimeFormat(pattern="uuuu-MM-dd") private LocalDate birthday; // 文字サイズを超えている場合は、切り出す。 @CsvColumn(number=4, label="備考") @CsvFixedSize(size=20, chopped=true) private String comment; // getter, setterは省略 }
固定長としてパディングする場合、サイズのカウント方法の考え方は、複数あります。
例えば、半角は1文字、全角は2文字分として換算する。 または、文字のバイト数で換算することもあります。
そこで、属性 paddingProcessor でパディング処理の実装クラスを切り替えることができます。
標準では以下の実装が提供されています。
- SimplePaddingProcessor - 文字の種別にかかわらず1文字としてカウントしてパディングします。
- CharWidthPaddingProcessor - 文字の幅(半角は1文字、全角は2文字)によってカウントしてパディングします。デフォルトの実装です。
- ByteSizePaddingProcessor - バイト数によってカウントしてパディングします。
import com.github.mygreen.supercsv.annotation.CsvBean; import com.github.mygreen.supercsv.annotation.CsvColumn; import com.github.mygreen.supercsv.annotation.CsvFixedSize; import com.github.mygreen.supercsv.builder.FixedSizeHeaderMapper; import com.github.mygreen.supercsv.cellprocessor.conversion.ByteSizePaddingProcessor; import com.github.mygreen.supercsv.cellprocessor.conversion.CharWidthPaddingProcessor; import com.github.mygreen.supercsv.cellprocessor.conversion.SimplePaddingProcessor; @CsvBean(header=true, headerMapper=FixedSizeHeaderMapper.class) public class SampleCsv { // 文字の種別にかかわらず1文字としてカウントしてパディングします。 @CsvColumn(number=1) @CsvFixedSize(size=10, paddingProcessor=SimplePaddingProcessor.class) private int id; // 文字の幅(半角は1文字、全角は2文字)によってカウントしてパディングします。 @CsvColumn(number=2) @CsvFixedSize(size=20, paddingProcessor=CharWidthPaddingProcessor.class) private String name; // バイト数によってカウントしてパディングします。 @CsvColumn(number=3) @CsvFixedSize(size=20, paddingProcessor=ByteSizePaddingProcessor.Windows31j.class) private String comment; // 以下、省略 }
ラベルによるカラムのマッピング
Beanの定義は、ラベルのみによるマッピングは、アノテーション @CsvColumn の属性 number を省略します。
従来の属性 number でカラム番号で指定することもできます。
import com.github.mygreen.supercsv.annotation.CsvBean; import com.github.mygreen.supercsv.annotation.CsvColumn; @CsvBean(header=true, validateHeader=true) public class SampleBean { // ラベルがフィールド名 @CsvColumn private int no; // 従来のカラム番号を指定 @CsvColumn(number=2) private String name; // ラベルだけ指定 @CsvColumn(label="生年月日") @CsvDateTimeFormat(pattern="uuuu/MM/dd") private LocalDate birthday; // カラム番号とラベルの両方を指定 @CsvColumn(number=4, label="備考") private String comment; // getter/setterの定義は省略 }
ラベルによるマッピングの定義で読み込むには、LazyCsvAnnotationBeanReader を使用します。
- 全件読み込む場合の使用方法は、基本的に既存の CsvAnnotationBeanReader と変わりません。
- 1件ずつ読み込む場合は、メソッド LazyCsvAnnotationBeanReader#init() を呼んでマッピング情報を初期化します。
import com.github.mygreen.supercsv.io.LazyCsvAnnotationBeanReader; import java.nio.charset.Charset; import java.nio.file.Files; import java.io.File; import java.util.ArrayList; import java.util.List; public class Sample { // 全レコードを一度に読み込む場合 public void sampleReadAll() { LazyCsvAnnotationBeanReader<SampleBean> csvReader = new LazyCsvAnnotationBeanReader<>( SampleBean.class, Files.newBufferedReader(new File("sample.csv").toPath(), Charset.forName("Windows-31j")), CsvPreference.STANDARD_PREFERENCE); List<SampleBean> list = csvReader.readAll(); csvReader.close(); } // レコードを1件ずつ読み込む場合 public void sampleRead() { LazyCsvAnnotationBeanReader<SampleBean> csvReader = new LazyCsvAnnotationBeanReader<>( SampleBean.class, Files.newBufferedReader(new File("sample.csv").toPath(), Charset.forName("Windows-31j")), CsvPreference.STANDARD_PREFERENCE); // ヘッダー行を読み込み初期化します csvReader.init(); List<SampleBean> list = new ArrayList<>(); SampleBean record = null; while((record = csvReader.read()) != null) { list.add(record); } csvReader.close(); } }
ファイルに書き出すときには、LazyCsvAnnotationBeanWriterを使用します。
- 全件読み出す場合の使用方法は、基本的に既存の CsvAnnotationBeanWriter と変わりません。
- 1件ずつ書き出す場合は、メソッド CsvAnnotationBeanWriter#init() を呼んでマッピング情報を初期化します。
- カラムの出力順は、フィールド名の昇順になります。
- 任意の順序でカラムを出力したい場合、メソッド #init("見出し1","見出し2",...) でヘッダー情報を直接指定し、初期化します。
import com.github.mygreen.supercsv.io.LazyCsvAnnotationBeanWriter; import java.nio.charset.Charset; import java.nio.file.Files; import java.io.File; import java.util.ArrayList; import java.util.List; import org.supercsv.prefs.CsvPreference; public class Sample { // 全レコードを一度に書き込む場合 public void sampleWriteAll() { LazyCsvAnnotationBeanWriter<UserCsv> csvWriter = new LazyCsvAnnotationBeanWriter<>( SampleCsv.class, Files.newBufferedWriter(new File("sample.csv").toPath(), Charset.forName("Windows-31j")), CsvPreference.STANDARD_PREFERENCE); // 書き出し用のデータの作成 List<SampleCsv> list = new ArrayList<>(); SampleCsv record1 = new SampleCsv(); record1.setNo(1); record1.setName("山田太郎"); record1.setBirthday(LocalDate.of(2000, 10, 1)); record1.setComment("あいうえお"); liad.add(record1); SampleCsv record2 = new SampleCsv(); record2.setNo(2); record2.setName("鈴木次郎"); record2.setBirthday(LocalDate.of(2012, 1, 2)); record2.setComment(null); liad.add(record2); // ヘッダー行と全レコードデータの書き出し csvWriter.writeAll(list); csvWriter.close(); } // レコードを1件ずつ書き出す場合 public void sampleWrite() { LazyCsvAnnotationBeanWriter<SampleCsv> csvWriter = new LazyCsvAnnotationBeanWriter<>( UserCsv.class, Files.newBufferedWriter(new File("sample.csv").toPath(), Charset.forName("Windows-31j")), CsvPreference.STANDARD_PREFERENCE); // 初期化を行います csvWriter.init(); // ヘッダー行の書き出し csvWriter.writeHeader(); // レコードのデータの書き出し SampleCsv record1 = new UserCsv(); record1.setNo(1); record1.setName("山田太郎"); record1.setBirthday(LocalDate.of(2000, 10, 1)); record1.setComment("あいうえお"); csvWriter.write(record1); SampleCsv record2 = new UserCsv(); record2.setNo(2); record2.setName("鈴木次郎"); record2.setBirthday(LocalDate.of(2012, 1, 2)); record2.setComment(null); csvWriter.write(record2); csvWrier.flush(); csvWrier.close(); } // 全レコードを一度に書き込む場合 - 任意のカラムの順番で出力 public void sampleWriteAll() { LazyCsvAnnotationBeanWriter<UserCsv> csvWriter = new LazyCsvAnnotationBeanWriter<>( SampleCsv.class, Files.newBufferedWriter(new File("sample.csv").toPath(), Charset.forName("Windows-31j")), CsvPreference.STANDARD_PREFERENCE); // カラムの順番指定して初期化します。 csvWriter.init("no", "name", "生年月日", "備考"); // 書き出し用のデータの作成 List<SampleCsv> list = new ArrayList<>(); //・・・省略 // ヘッダー行と全レコードデータの書き出し csvWriter.writeAll(list); csvWriter.close(); } }
Java 1.8.0_121以降でJavaScriptを含むJavadocを生成する(maven)
JDK 1.8.0_121以降から、JavadocにJavaScriptを含むJavaScriptを含む場合、オプション「--allow-script-in-comments」が必要になり、次のようなエラーがでるようになりました。
[INFO] ------------------------------------------------------------------------ [INFO] BUILD FAILURE [INFO] ------------------------------------------------------------------------ [INFO] Total time: 4.083 s [INFO] Finished at: 2017-09-01T23:49:17+09:00 [INFO] Final Memory: 17M/226M [INFO] ------------------------------------------------------------------------ [ERROR] Failed to execute goal org.apache.maven.plugins:maven-javadoc-plugin:2.10.4:javadoc (default-cli) on project XXX: An error has occurred in JavaDocs report generation: [ERROR] Exit code: 1 - javadoc: エラー - -headerの引数にJavaScriptが含まれています。 [ERROR] --allow-script-in-commentsを使用して、JavaScriptの使用を許可してください。 [ERROR] [ERROR] Command line was: C:\usr\java\jdk1.8.0_121\jre\..\bin\javadoc.exe -J-Xmx512m @options @packages ・・・
対応として、エラーメッセージの通りに指定します。
maven-javadoc-pluginを使用している場合は次のように指定します。
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-javadoc-plugin</artifactId> <version>2.10.4</version> <configuration> <nohelp>true</nohelp> <charset>UTF-8</charset> <encoding>UTF-8</encoding> <docencoding>UTF-8</docencoding> <locale>ja_JP</locale> <maxmemory>512m</maxmemory> <links> <link>https://docs.oracle.com/javase/jp/8/docs/api/</link> <link>http://super-csv.github.io/super-csv/apidocs/</link> </links> <stylesheetfile>${basedir}/src/main/javadoc/stylesheet.css</stylesheetfile> <docfilessubdirs>true</docfilessubdirs> <!-- スクリプトの埋め込む記述を許可する指定 --> <additionalparam>--allow-script-in-comments</additionalparam> <!-- ヘッダーにスクリプトを埋め込む記述 --> <header>${project.name} ${project.version} <![CDATA[ <link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.1.0/styles/default.min.css"> <script src="http://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.1.0/highlight.min.js"></script> <script src="https://code.jquery.com/jquery-1.12.0.min.js"></script> <script> $(document).ready(function() { $('pre.highlight code').each(function(i, block) { hljs.highlightBlock(block); }); }); </script> ]]> </header> </configuration> <executions> <execution> <phase>package</phase> <goals> <goal>jar</goal> </goals> </execution> </executions> </plugin>
Super CSV Annotation 2.0のリリース
久しぶりの更新です。
JavaでCSVファイルを扱うためのライブラリ Super CSV に対してアノテーション機能を付け加えた独自のライブラリ Super CSV Annotation のver2.0をリリースしました。
- マニュアル
- ソース(GitHub)
主な変更点
作り直したため、互換性はなくなりましたが、基本的な使用方法は変わりません。
パッケージ名、クラス名は大きく変わっています。
- トリムなどの変換用のアノテーションを追加。
- 今までは、XXXConverterアノテーションに集約していたものを分離しました。
- バリデーション用のアノテーションを追加。
- これも、XXXConverterアノテーションに集約していたものを分離しました。
- 書式指定用のアノテーションを変更。
- 今までは、XXXConverterという名称から、XXXFormatに変更しました。
- BeanValdiationのように各種アノテーションを合成して、新たなアノテーションが作成できます。
機能的には変わりませんが、上記の機能に対する独自の拡張やアノテーションの追加が圧倒的に容易にできるようになりました。
機能一覧は、マニュアルの目次 を見ていただければわかります。
また、Bean Validationのように属性「groups」でアノテーションを適用するケースを絞り込めるようにしました。
よく使う、読み込み、書き込み時の区別は、別な属性「cases」でできるようにしました。
さらに、Bean Validationの使い勝手の悪い、順番の指定ができるようにしています。
順番や適用するケースが指定できることで、かなり柔軟な加工ができるようになりました。
まあ、現在、仕様策定中の Bean Validation 2.0 からは順番の指定ができるようになるそうですが。
基本的な使い方
マニュアルの内容そのままです。
pom.xmlには下記を追加。
<dependency> <groupId>com.github.mygreen</groupId> <artifactId>super-csv-annotation</artifactId> <version>2.0</version> </dependency>
Beanの定義
基本的なアノテーション @CsvBean、@CsvColumn は変わりません。
ただし、@CsvColumnの番号指定は index→numberに代わり、1から指定するようにしました。
カラム数が多くなるとこれは設計書からBeanを定義するとき、個人的によくずれて定義してしまったためです。
import java.time.LocalDate; import com.github.mygreen.supercsv.annotation.CsvBean; import com.github.mygreen.supercsv.annotation.CsvColumn; import com.github.mygreen.supercsv.annotation.constraint.CsvNumberMin; import com.github.mygreen.supercsv.annotation.constraint.CsvRequire; import com.github.mygreen.supercsv.annotation.constraint.CsvUnique; import com.github.mygreen.supercsv.annotation.conversion.CsvDefaultValue; import com.github.mygreen.supercsv.annotation.conversion.CsvNullConvert; import com.github.mygreen.supercsv.annotation.format.CsvDateTimeFormat; import com.github.mygreen.supercsv.annotation.format.CsvNumberFormat; import com.github.mygreen.supercsv.builder.BuildCase; @CsvBean public class SampleCsv { @CsvColumn(number=1, label="ID") @CsvRequire // 必須チェックを行う @CsvUnique(order=1) // 全レコード内で値がユニークかチェックする(順番指定) @CsvNumberMin(value="0", order=2) // 最小値かどかチェックする(順番指定) private Integer id; @CsvColumn(number=2, label="名前") private String name; @CsvColumn(number=3, label="誕生日") @CsvDateTimeFormat(pattern="yyyy年MM月dd日") // 日時の書式を指定する private LocalDate birthday; @CsvColumn(number=4, label="給料") @CsvNumberFormat(pattern="#,###0") // 数値の書式を指定する @CsvDefaultValue(value="N/A", cases=BuildCase.Write) // 書き込み時に値がnull(空)の場合、「N/A」として出力します。 @CsvNullConvert(value="N/A", cases=BuildCase.Read) // 読み込み時に値が「N/A」のとき、nullとして読み込みます。 private Integer salary; // getter/setterは省略 }
読み書きの方法
読み書きするためのクラス CsvAnnotationBeanReader/CsvAnnotationBeanWriterは大きく変わりません。
ただし、一度に読み書きする readAll()/writeAll() メソッドを追加しました。
import com.github.mygreen.supercsv.io.CsvAnnotationBeanReader; import com.github.mygreen.supercsv.io.CsvAnnotationBeanWriter; import java.nio.charset.Charset; import java.nio.file.Files; import java.io.File; import java.util.ArrayList; import java.util.List; import org.supercsv.prefs.CsvPreference; public class Sample { // 全レコードを一度に読み込む場合 public void sampleReadAll() { CsvAnnotationBeanReader<SampleCsv > csvReader = new CsvAnnotationBeanReader<>( SampleCsv .class, Files.newBufferedReader(new File("sample.csv").toPath(), Charset.forName("Windows-31j")), CsvPreference.STANDARD_PREFERENCE); List<SampleCsv > list = csvReader.readAll(); csvReader.close(); } // レコードを1件ずつ読み込む場合 public void sampleRead() { CsvAnnotationBeanReader<SampleCsv > csvReader = new CsvAnnotationBeanReader<>( SampleCsv .class, Files.newBufferedReader(new File("sample.csv").toPath(), Charset.forName("Windows-31j")), CsvPreference.STANDARD_PREFERENCE); List<SampleCsv > list = new ArrayList<>(); // ヘッダー行の読み込み String headers[] = csvReader.getHeader(true); UserCsv record = null; while((record = csvReader.read()) != null) { list.add(record); } csvReader.close(); } // 全レコードを一度に書き込む場合 public void sampleWriteAll() { CsvAnnotationBeanWriter<UserCsv> csvWriter = new CsvAnnotationBeanWriter<>( UserCsv.class, Files.newBufferedWriter(new File("sample.csv").toPath(), Charset.forName("Windows-31j")), CsvPreference.STANDARD_PREFERENCE); // 書き込み用のデータの作成 List<SampleCsv > list = new ArrayList<>(); SampleCsv record1 = new SampleCsv (); record1.setNo(1); record1.setName("山田太郎"); liad.add(record1); SampleCsv record2 = new SampleCsv (); record2.setNo(2); record2.setName("鈴木次郎"); liad.add(record2); // ヘッダー行と全レコードデータの書き込み csvWriter.writeAll(list); csvWriter.close(); } // レコードを1件ずつ読み込む場合 public void sampleWrite() { CsvAnnotationBeanWriter<SampleCsv > csvWriter = new CsvAnnotationBeanWriter<>( SampleCsv .class, Files.newBufferedWriter(new File("sample.csv").toPath(), Charset.forName("Windows-31j")), CsvPreference.STANDARD_PREFERENCE); // ヘッダー行の書き込み csvWriter.writeHeader(); // レコードのデータの書き込み SampleCsv record1 = new SampleCsv (); record1.setNo(1); record1.setName("山田太郎"); csvWriter.write(record1); SampleCsv record2 = new SampleCsv (); record2.setNo(2); record2.setName("鈴木次郎"); csvWriter.write(record2); csvWrier.flush(); csvWrier.close(); } }