package com.gh.mygreen.xlsmapper.xml;
import static org.junit.Assert.*;
import static org.hamcrest.Matchers.*;
import static com.gh.mygreen.xlsmapper.TestUtils.*;
import java.awt.Point;
import java.io.File;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.util.Date;
import java.util.List;
import java.util.Map;
import static com.gh.mygreen.xlsmapper.xml.XmlBuilder.*;
import org.junit.BeforeClass;
import org.junit.Test;
import com.gh.mygreen.xlsmapper.annotation.LabelledCellType;
import com.gh.mygreen.xlsmapper.annotation.RecordTerminal;
import com.gh.mygreen.xlsmapper.annotation.XlsCell;
import com.gh.mygreen.xlsmapper.annotation.XlsConverter;
import com.gh.mygreen.xlsmapper.annotation.XlsHint;
import com.gh.mygreen.xlsmapper.annotation.XlsHorizontalRecords;
import com.gh.mygreen.xlsmapper.annotation.XlsLabelledCell;
import com.gh.mygreen.xlsmapper.annotation.XlsSheet;
import com.gh.mygreen.xlsmapper.annotation.XlsSheetName;
import com.gh.mygreen.xlsmapper.xml.bind.AnnotationInfo;
import com.gh.mygreen.xlsmapper.xml.bind.ClassInfo;
import com.gh.mygreen.xlsmapper.xml.bind.FieldInfo;
import com.gh.mygreen.xlsmapper.xml.bind.MethodInfo;
import com.gh.mygreen.xlsmapper.xml.bind.XmlInfo;
/**
* {@link XmlBuilder}のテスタ
*
* @version 1.4.1
* @since 1.1
* @author T.TSUCHIE
*
*/
public class XmlBuilderTest {
/**
* テスト結果ファイルの出力ディレクトリ
*/
private static File OUT_DIR;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
OUT_DIR = createOutDir();
}
/**
* アノテーションがないクラスに設定する。
*/
@Test
public void test_simple() throws Exception {
XmlInfo xmlInfo = createXml()
.classInfo(createClass(SimpleSheet.class)
.annotation(createAnnotation(XlsSheet.class)
.attribute("name", "単純なシート")
.buildAnnotation())
.field(createField("sheetName")
.annotation(createAnnotation(XlsSheetName.class)
.buildAnnotation())
.buildField())
.field(createField("name")
.annotation(createAnnotation(XlsLabelledCell.class)
.attribute("label", "名称")
.attribute("type", LabelledCellType.Right)
.buildAnnotation())
.annotation(createAnnotation(XlsConverter.class)
.attribute("trim", true)
.attribute("defaultValue", "-")
.buildAnnotation())
.buildField())
.method(createMethod("setRecords")
.annotation(createAnnotation(XlsHorizontalRecords.class)
.attribute("tableLabel", "名簿一覧")
.attribute("terminal", RecordTerminal.Border)
.buildAnnotation())
.buildMethod())
.buildClass())
.buildXml();
System.out.println(xmlInfo.toXml());
AnnotationReader reader = new AnnotationReader(xmlInfo);
// クラス定義の読み込み
Annotation[] classAnnos = reader.getAnnotations(SimpleSheet.class);
XlsSheet sheetAnno = select(classAnnos, XlsSheet.class);
assertThat(sheetAnno.name(), is("単純なシート"));
// クラス定義の読み込み(アノテーションを指定)
sheetAnno = reader.getAnnotation(SimpleSheet.class, XlsSheet.class);
assertThat(sheetAnno.name(), is("単純なシート"));
// フィールド定義の読み込み
Annotation[] nameAnnos = reader.getAnnotations(SimpleSheet.class, SimpleSheet.class.getDeclaredField("name"));
XlsLabelledCell labeldCellAnno = select(nameAnnos, XlsLabelledCell.class);
assertThat(labeldCellAnno.label(), is("名称"));
assertThat(labeldCellAnno.type(), is(LabelledCellType.Right));
XlsConverter converterAnno = select(nameAnnos, XlsConverter.class);
assertThat(converterAnno.trim(), is(true));
assertThat(converterAnno.defaultValue(), is("-"));
// フィールド定義の読み込み(アノテーションを指定)
labeldCellAnno = reader.getAnnotation(SimpleSheet.class, SimpleSheet.class.getDeclaredField("name"), XlsLabelledCell.class);
assertThat(labeldCellAnno.label(), is("名称"));
assertThat(labeldCellAnno.type(), is(LabelledCellType.Right));
// メソッドの定義の読み込み
Annotation[] recordsAnnos = reader.getAnnotations(SimpleSheet.class,
SimpleSheet.class.getDeclaredMethod("setRecords", List.class));
XlsHorizontalRecords horizontalRecordsAnno = select(recordsAnnos, XlsHorizontalRecords.class);
assertThat(horizontalRecordsAnno.tableLabel(), is("名簿一覧"));
assertThat(horizontalRecordsAnno.terminal(), is(RecordTerminal.Border));
// メソッドの定義の読み込み(アノテーションを指定)
horizontalRecordsAnno = reader.getAnnotation(SimpleSheet.class,
SimpleSheet.class.getDeclaredMethod("setRecords", List.class), XlsHorizontalRecords.class);
assertThat(horizontalRecordsAnno.tableLabel(), is("名簿一覧"));
assertThat(horizontalRecordsAnno.terminal(), is(RecordTerminal.Border));
}
/**
* クラスに定義されている定義の上書き
* ・XML中のoverride属性がfalseの場合。
* @throws Exception
*/
@Test
public void test_override() throws Exception {
XmlInfo xmlInfo = createXml()
.classInfo(createClass(OrverrideSheet.class)
.override(true)
.annotation(createAnnotation(XlsSheet.class)
.attribute("name", "")
.attribute("regex", "リスト.+")
.buildAnnotation())
.field(createField("name")
.override(true)
.annotation(createAnnotation(XlsLabelledCell.class)
.attribute("label", "クラス名")
.attribute("type", LabelledCellType.Bottom)
.buildAnnotation())
.buildField())
.method(createMethod("setRecords")
.override(true)
.annotation(createAnnotation(XlsHorizontalRecords.class)
.attribute("tableLabel", "名簿一覧")
.attribute("terminal", RecordTerminal.Border)
.buildAnnotation())
.buildMethod())
.buildClass())
.buildXml();
System.out.println(xmlInfo.toXml());
AnnotationReader reader = new AnnotationReader(xmlInfo);
// クラス定義の読み込み
XlsSheet sheetAnno = reader.getAnnotation(OrverrideSheet.class, XlsSheet.class);
assertThat(sheetAnno.name(), is(""));
assertThat(sheetAnno.regex(), is("リスト.+"));
// フィールド定義の読み込み
Annotation[] nameAnnos = reader.getAnnotations(OrverrideSheet.class, OrverrideSheet.class.getDeclaredField("name"));
// フィールド - XMLに定義している
XlsLabelledCell labeldCellAnno = select(nameAnnos, XlsLabelledCell.class);
assertThat(labeldCellAnno.label(), is("クラス名"));
assertThat(labeldCellAnno.type(), is(LabelledCellType.Bottom));
// フィールド - XMLに定義していない
XlsConverter converterAnno = select(nameAnnos, XlsConverter.class);
assertThat(converterAnno.trim(), is(true));
assertThat(converterAnno.shrinkToFit(), is(true));
assertThat(converterAnno.defaultValue(), is("-"));
XlsHint hintAnno1 = select(nameAnnos, XlsHint.class);
assertThat(hintAnno1.order(), is(1));
// メソッド定義の読み込み
Annotation[] recordsAnnos = reader.getAnnotations(OrverrideSheet.class, OrverrideSheet.class.getDeclaredMethod("setRecords", List.class));
// メソッド - XMLに定義している
XlsHorizontalRecords horizontalRecordsAnno = select(recordsAnnos, XlsHorizontalRecords.class);
assertThat(horizontalRecordsAnno.tableLabel(), is("名簿一覧"));
assertThat(horizontalRecordsAnno.terminal(), is(RecordTerminal.Border));
// メソッド - XMLに定義していない
XlsHint hintAnno2 = select(recordsAnnos, XlsHint.class);
assertThat(hintAnno2.order(), is(2));
}
/**
* InputStreamを取得するためのサンプル。
*/
@Test
public void test_sample() throws Exception {
InputStream xmlIn = createXml()
.classInfo(createClass(SimpleSheet.class)
.override(true)
.annotation(createAnnotation(XlsSheet.class)
.attribute("name", "サンプル")
.buildAnnotation())
.buildClass())
.buildXml()
.toInputStream();
assertThat(xmlIn, is(not(nullValue())));
xmlIn.close();
// System.out.println(xmlInfo.toXml());
}
/**
* XMLの書き込みテスト
*/
@Test
public void test_xml_io() throws Exception {
XmlInfo xmlInfo = createXml()
.classInfo(createClass(SimpleSheet.class)
.annotation(createAnnotation(XlsSheet.class)
.attribute("name", "単純なシート")
.buildAnnotation())
.field(createField("sheetName")
.annotation(createAnnotation(XlsSheetName.class)
.buildAnnotation())
.buildField())
.field(createField("name")
.annotation(createAnnotation(XlsLabelledCell.class)
.attribute("label", "名称")
.attribute("type", LabelledCellType.Right)
.buildAnnotation())
.annotation(createAnnotation(XlsConverter.class)
.attribute("trim", true)
.attribute("defaultValue", "-")
.buildAnnotation())
.buildField())
.method(createMethod("setRecords")
.annotation(createAnnotation(XlsHorizontalRecords.class)
.attribute("tableLabel", "名簿一覧")
.attribute("terminal", RecordTerminal.Border)
.buildAnnotation())
.buildMethod())
.buildClass())
.buildXml();
File file = new File(OUT_DIR, "anno_test.xml");
XmlIO.save(xmlInfo, file, "Windows-31j");
XmlInfo readInfo = XmlIO.load(file, "Windows-31j");
assertThat(readInfo, is(not(nullValue())));
}
/**
* 同じクラス名を追加した時のテスト
*/
@Test
public void test_XmlInfo_class_duplicate() {
XmlInfo xmlInfo = createXml()
.classInfo(createClass(SimpleSheet.class)
.field(createField("field1").buildField())
.buildClass())
.classInfo(createClass(SimpleSheet.class)
.field(createField("field2").buildField())
.buildClass())
.buildXml();
assertThat(xmlInfo.getClassInfos(), hasSize(1));
assertThat(xmlInfo.containsClassInfo(SimpleSheet.class.getName()), is(true));
assertThat(xmlInfo.containsClassInfo(OrverrideSheet.class.getName()), is(false));
ClassInfo classInfo = xmlInfo.getClassInfo(SimpleSheet.class.getName());
assertThat(classInfo.getFieldInfo("field1"), is(nullValue()));
assertThat(classInfo.getFieldInfo("field2"), is(not(nullValue())));
}
/**
* 同じアノテーションを追加した時のテスト
*/
@Test
public void test_ClassInfo_annotation_duplicate() {
ClassInfo classInfo = createClass(SimpleSheet.class)
.annotation(createAnnotation(XlsSheet.class)
.attribute("name", "Sheet1")
.buildAnnotation())
.annotation(createAnnotation(XlsSheet.class)
.attribute("regex", "Sheet.+")
.buildAnnotation())
.buildClass();
assertThat(classInfo.getAnnotationInfos(), hasSize(1));
assertThat(classInfo.containsAnnotationInfo(XlsSheet.class.getName()), is(true));
assertThat(classInfo.containsAnnotationInfo(XlsSheetName.class.getName()), is(false));
AnnotationInfo annoInfo = classInfo.getAnnotationInfo(XlsSheet.class.getName());
assertThat(annoInfo.getAttribute("name"), is(nullValue()));
assertThat(annoInfo.getAttribute("regex"), is(not(nullValue())));
}
/**
* 同じフィールドを追加した時のテスト
*/
@Test
public void test_ClassInfo_field_duplicate() {
ClassInfo classInfo = createClass(SimpleSheet.class)
.field(createField("field1")
.annotation(createAnnotation(XlsLabelledCell.class)
.attribute("label", "クラス名")
.buildAnnotation())
.buildField())
.field(createField("field1")
.annotation(createAnnotation(XlsHorizontalRecords.class)
.attribute("tableLabel", "名簿一覧")
.buildAnnotation())
.buildField())
.buildClass();
assertThat(classInfo.getFieldInfos(), hasSize(1));
assertThat(classInfo.containsFieldInfo("field1"), is(true));
assertThat(classInfo.containsFieldInfo("field2"), is(false));
FieldInfo fieldInfo = classInfo.getFieldInfo("field1");
assertThat(fieldInfo.containsAnnotationInfo(XlsLabelledCell.class.getName()), is(false));
assertThat(fieldInfo.containsAnnotationInfo(XlsHorizontalRecords.class.getName()), is(true));
}
/**
* 同じメソッドを追加した時のテスト
*/
@Test
public void test_ClassInfo_method_duplicate() {
ClassInfo classInfo = createClass(SimpleSheet.class)
.method(createMethod("method1")
.annotation(createAnnotation(XlsLabelledCell.class)
.attribute("label", "クラス名")
.buildAnnotation())
.buildMethod())
.method(createMethod("method1")
.annotation(createAnnotation(XlsHorizontalRecords.class)
.attribute("tableLabel", "名簿一覧")
.buildAnnotation())
.buildMethod())
.buildClass();
assertThat(classInfo.getMethodInfos(), hasSize(1));
assertThat(classInfo.containsMethodInfo("method1"), is(true));
assertThat(classInfo.containsMethodInfo("method2"), is(false));
MethodInfo fieldInfo = classInfo.getMethodInfo("method1");
assertThat(fieldInfo.containsAnnotationInfo(XlsLabelledCell.class.getName()), is(false));
assertThat(fieldInfo.containsAnnotationInfo(XlsHorizontalRecords.class.getName()), is(true));
}
/**
* 同じアノテーションを追加した時のテスト
*/
@Test
public void test_FieldInfo_annotation_duplicate() {
FieldInfo fieldInfo = createField("field1")
.annotation(createAnnotation(XlsLabelledCell.class)
.attribute("label", "クラス名")
.buildAnnotation())
.annotation(createAnnotation(XlsLabelledCell.class)
.attribute("type", LabelledCellType.Bottom)
.buildAnnotation())
.buildField();
assertThat(fieldInfo.getAnnotationInfos(), hasSize(1));
assertThat(fieldInfo.containsAnnotationInfo(XlsLabelledCell.class.getName()), is(true));
assertThat(fieldInfo.containsAnnotationInfo(XlsCell.class.getName()), is(false));
AnnotationInfo annoInfo = fieldInfo.getAnnotationInfo(XlsLabelledCell.class.getName());
assertThat(annoInfo.getAttribute("label"), is(nullValue()));
assertThat(annoInfo.getAttribute("type"), is(not(nullValue())));
}
/**
* 同じアノテーションを追加した時のテスト
*/
@Test
public void test_MethodInfo_annotation_duplicate() {
MethodInfo methodInfo = createMethod("method1")
.annotation(createAnnotation(XlsLabelledCell.class)
.attribute("label", "クラス名")
.buildAnnotation())
.annotation(createAnnotation(XlsLabelledCell.class)
.attribute("type", LabelledCellType.Bottom)
.buildAnnotation())
.buildMethod();
assertThat(methodInfo.getAnnotationInfos(), hasSize(1));
assertThat(methodInfo.containsAnnotationInfo(XlsLabelledCell.class.getName()), is(true));
assertThat(methodInfo.containsAnnotationInfo(XlsCell.class.getName()), is(false));
AnnotationInfo annoInfo = methodInfo.getAnnotationInfo(XlsLabelledCell.class.getName());
assertThat(annoInfo.getAttribute("label"), is(nullValue()));
assertThat(annoInfo.getAttribute("type"), is(not(nullValue())));
}
/**
* アノテーションの同じ属性を追加したときのテスト
*/
@Test
public void test_AnnotationInfo_attribute_duplicatte() {
AnnotationInfo annoInfo = createAnnotation(XlsLabelledCell.class)
.attribute("label", "test1")
.attribute("label", "test2")
.buildAnnotation();
assertThat(annoInfo.getAttributeInfos(), hasSize(1));
assertThat(annoInfo.containsAttribute("label"), is(true));
assertThat(annoInfo.containsAttribute("type"), is(false));
assertThat(annoInfo.getAttribute("label"), is("\"test2\""));
}
private <A extends Annotation> A select(Annotation[] annos, Class<A> clazz) {
for(Annotation anno : annos) {
if(anno.annotationType().equals(clazz)) {
return (A) anno;
}
}
return null;
}
/**
* アノテーション定義がない単純シート
*
*/
private static class SimpleSheet {
private Map<String, Point> positions;
private Map<String, String> labels;
private String sheetName;
private String name;
private List<NormalRecord> records;
public List<NormalRecord> getRecords() {
return records;
}
public void setRecords(List<NormalRecord> records) {
this.records = records;
}
}
/**
* アノテーション定義の上書き
*/
@XlsSheet(name="テスト")
private static class OrverrideSheet {
private Map<String, Point> positions;
private Map<String, String> labels;
@XlsSheetName
private String sheetName;
@XlsHint(order=1)
@XlsConverter(trim=true, shrinkToFit=true, defaultValue="-")
@XlsLabelledCell(label="名称", type=LabelledCellType.Right)
private String name;
private List<NormalRecord> records;
public List<NormalRecord> getRecords() {
return records;
}
@XlsHint(order=2)
@XlsHorizontalRecords(tableLabel="クラス名", terminal=RecordTerminal.Empty)
public void setRecords(List<NormalRecord> records) {
this.records = records;
}
}
private static class NormalRecord {
private Map<String, Point> positions;
private Map<String, String> labels;
private int no;
private String name;
private Date updateTime;
}
}