AnnotationMappingInfo.java

  1. package com.gh.mygreen.xlsmapper.xml.bind;

  2. import java.io.ByteArrayInputStream;
  3. import java.io.InputStream;
  4. import java.io.Serializable;
  5. import java.io.StringWriter;
  6. import java.nio.charset.StandardCharsets;
  7. import java.util.ArrayList;
  8. import java.util.Collection;
  9. import java.util.List;

  10. import javax.xml.bind.JAXB;
  11. import javax.xml.bind.annotation.XmlElement;
  12. import javax.xml.bind.annotation.XmlRootElement;

  13. import com.gh.mygreen.xlsmapper.util.ArgUtils;


  14. /**
  15.  * XMLで定義したアノテーションの設定情報。
  16.  *
  17.  * XMLの使用:
  18.  * <pre class="highlight"><code class="xml">
  19.  * {@literal <!-- ルート要素--> }
  20.  * {@literal <annotations>}
  21.  *     ・・・
  22.  * {@literal </annotations>}
  23.  * </code></pre>
  24.  *
  25.  * @version 2.0
  26.  * @since 0.5
  27.  * @author T.TSUCHIE
  28.  *
  29.  */
  30. @XmlRootElement(name="annotations")
  31. public class AnnotationMappingInfo implements Serializable {
  32.    
  33.     /** serialVersionUID */
  34.     private static final long serialVersionUID = 1L;
  35.    
  36.     private List<ClassInfo> classInfos = new ArrayList<>();
  37.    
  38.     /**
  39.      * ビルダクラスのインスタンスを取得する。
  40.      * @since 1.1
  41.      * @return
  42.      */
  43.     public static Builder builder() {
  44.         return new Builder();
  45.     }
  46.    
  47.     public AnnotationMappingInfo() {
  48.        
  49.     }
  50.    
  51.     private AnnotationMappingInfo(final Builder builder) {
  52.         setClassInfos(builder.classInfos);
  53.     }
  54.    
  55.     /**
  56.      * クラス情報を追加する。
  57.      * <p>ただし、既に同じクラス名が存在する場合は、それと入れ替えされます。</p>
  58.      * @param classInfo FQCN(完全限定クラス名)を指定します。
  59.      * @throws IllegalArgumentException classInfo is null.
  60.      */
  61.     public void addClassInfo(final ClassInfo classInfo) {
  62.         ArgUtils.notNull(classInfo, "classInfo");
  63.        
  64.         removeClassInfo(classInfo.getClassName());
  65.         this.classInfos.add(classInfo);
  66.     }
  67.    
  68.     /**
  69.      * 複数のクラス上方を追加する。
  70.      * @since 2.0
  71.      * @param classInfos 複数のクラス情報
  72.      */
  73.     public void addClassInfos(Collection<ClassInfo> classInfos) {
  74.         classInfos.forEach(info -> addClassInfo(info));
  75.     }
  76.    
  77.     /**
  78.      * クラス名を指定してクラス情報を取得する。
  79.      * @param className FQCN(完全限定クラス名)を指定します。
  80.      * @return 存在しないクラス名の場合、nullを返します。
  81.      */
  82.     public ClassInfo getClassInfo(final String className) {
  83.         for(ClassInfo item : classInfos) {
  84.             if(item.getClassName().equals(className)) {
  85.                 return item;
  86.             }
  87.         }
  88.         return null;
  89.     }
  90.    
  91.     /**
  92.      * 指定したクラスが含まれるかどうか。
  93.      * @since 1.1
  94.      * @param className FQCN(完全限定クラス名)を指定します。
  95.      * @return true:指定したクラス名を含む場合。
  96.      */
  97.     public boolean containsClassInfo(final String className) {
  98.         return getClassInfo(className) != null;
  99.     }
  100.    
  101.     /**
  102.      * 指定したクラス情報を削除します。
  103.      * @since 1.4.1
  104.      * @param className FQCN(完全限定クラス名)を指定します。
  105.      * @return true:指定したクラス名を含み、それが削除できた場合。
  106.      */
  107.     public boolean removeClassInfo(final String className) {
  108.        
  109.         final ClassInfo existInfo = getClassInfo(className);
  110.         if(existInfo != null) {
  111.             this.classInfos.remove(existInfo);
  112.             return true;
  113.         }
  114.        
  115.         return false;
  116.        
  117.     }
  118.    
  119.     @Override
  120.     public String toString() {
  121.         StringBuilder sb = new StringBuilder();
  122.         sb.append("XmlInfo:");
  123.        
  124.         for(ClassInfo clazz : classInfos) {
  125.             sb.append("\n  ").append(clazz.toString());
  126.         }
  127.        
  128.         return sb.toString();
  129.     }
  130.    
  131.     /**
  132.      * JAXB用のクラス情報を設定するメソッド。
  133.      * <p>XMLの読み込み時に呼ばれます。
  134.      *  <br>ただし、Java8からはこのメソッドは呼ばれず、{@link #getClassInfos()} で取得したインスタンスに対して要素が追加されます。
  135.      * </p>
  136.      * <p>既存の情報はクリアされます。</p>
  137.      * @since 1.1
  138.      * @param classInfos クラス情報
  139.      */
  140.     public void setClassInfos(final List<ClassInfo> classInfos) {
  141.         if(classInfos == this.classInfos) {
  142.             // Java7の場合、getterで取得したインスタンスをそのまま設定するため、スキップする。
  143.             return;
  144.         }
  145.        
  146.         this.classInfos.clear();
  147.         for(ClassInfo item : classInfos) {
  148.             addClassInfo(item);
  149.         }
  150.        
  151.     }
  152.    
  153.     /**
  154.      * JAXB用のクラス情報を取得するメソッド。
  155.      * <p>XMLの書き込み時に呼ばれます。
  156.      *  <br>Java8から読み込み時に呼ばれるようになり、取得したインスタンスに対して、読み込んだ要素が呼ばれます。
  157.      * </p>
  158.      * @since 1.1
  159.      * @return
  160.      */
  161.     @XmlElement(name="class")
  162.     public List<ClassInfo> getClassInfos() {
  163.         return classInfos;
  164.     }
  165.    
  166.     /**
  167.      * XML(テキスト)として返す。
  168.      * <p>JAXB標準の設定でXMLを作成します。</p>
  169.      * @since 1.1
  170.      * @return XML情報。
  171.      */
  172.     public String toXml() {
  173.        
  174.         StringWriter writer = new StringWriter();
  175.         JAXB.marshal(this, writer);
  176.         writer.flush();
  177.        
  178.         return writer.toString();
  179.        
  180.     }
  181.    
  182.     /**
  183.      * {@link InputStream}として返す。
  184.      * <p>XlsLoaderなどに直接渡せる形式。</p>
  185.      * <p>{@link #toXml()}にてXMLに変換後に、InputStreamにサイド変換する。</p>
  186.      * @since 1.1
  187.      * @return XML情報。
  188.      */
  189.     public InputStream toInputStream() {
  190.        
  191.         String text = toXml();
  192.         return new ByteArrayInputStream(text.getBytes(StandardCharsets.UTF_8));
  193.        
  194.     }
  195.    
  196.     /**
  197.      * {@link AnnotationMappingInfo}を組み立てるためのクラス。
  198.      *
  199.      */
  200.     public static final class Builder {
  201.        
  202.         private List<ClassInfo> classInfos;
  203.        
  204.         private Builder() {
  205.             this.classInfos = new ArrayList<>();
  206.         }
  207.        
  208.         /**
  209.          * 組み立てた{@link AnnotationMappingInfo}のインスタンスを返す。
  210.          * @return {@link AnnotationMappingInfo}オブジェクト。
  211.          */
  212.         public AnnotationMappingInfo buildXml() {
  213.             return new AnnotationMappingInfo(this);
  214.         }
  215.        
  216.         /**
  217.          * クラス情報を追加する。
  218.          * @param classInfo クラス情報
  219.          * @return
  220.          * @throws IllegalArgumentException classInfo is null
  221.          */
  222.         public Builder classInfo(final ClassInfo classInfo) {
  223.             ArgUtils.notNull(classInfo, "classInfo");
  224.             this.classInfos.add(classInfo);
  225.             return this;
  226.         }
  227.        
  228.     }
  229. }