FieldInfo.java

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

  2. import java.io.Serializable;
  3. import java.util.ArrayList;
  4. import java.util.List;

  5. import javax.xml.bind.annotation.XmlAttribute;
  6. import javax.xml.bind.annotation.XmlElement;

  7. import com.gh.mygreen.xlsmapper.util.ArgUtils;
  8. import com.gh.mygreen.xlsmapper.util.Utils;


  9. /**
  10.  * XMLのフィールド情報を保持するクラス。
  11.  *
  12.  * @version 1.1
  13.  * @since 1.0
  14.  * @author T.TSUCHIE
  15.  *
  16.  */
  17. public class FieldInfo implements Serializable {
  18.    
  19.     /** serialVersionUID */
  20.     private static final long serialVersionUID = 1L;
  21.    
  22.     private String fieldName;
  23.    
  24.     private boolean override;
  25.    
  26.     private List<AnnotationInfo> annotationInfos = new ArrayList<>();
  27.    
  28.     /**
  29.      * ビルダクラスのインスタンスを取得する。
  30.      * @since 1.1
  31.      * @return
  32.      */
  33.     public static Builder builder() {
  34.         return new Builder();
  35.     }
  36.    
  37.     public FieldInfo() {
  38.        
  39.     }
  40.    
  41.     private FieldInfo(final Builder builder) {
  42.         this.fieldName = builder.fieldName;
  43.         this.override = builder.override;
  44.         setAnnotationInfos(builder.annotationInfos);
  45.     }
  46.    
  47.     @Override
  48.     public String toString() {
  49.         StringBuilder sb = new StringBuilder();
  50.         sb.append("FieldInfo")
  51.             .append(String.format(" [name=%s]", getFieldName()))
  52.             .append(String.format(" [override=%b]", isOverride()));
  53.        
  54.         for(AnnotationInfo anno : annotationInfos) {
  55.             sb.append("  ").append(anno.toString());
  56.         }
  57.        
  58.         return sb.toString();
  59.     }
  60.    
  61.     /**
  62.      * フィールド名を取得する
  63.      * @return フィールド名
  64.      */
  65.     public String getFieldName() {
  66.         return fieldName;
  67.     }
  68.    
  69.     /**
  70.      * フィールド名を設定する
  71.      * @param fieldName フィールド名。
  72.      * @throws IllegalArgumentException fieldName is empty.
  73.      */
  74.     @XmlAttribute(name="name", required=true)
  75.     public void setFieldName(final String fieldName) {
  76.         ArgUtils.notEmpty(fieldName, "fieldName");
  77.         this.fieldName = fieldName;
  78.     }
  79.    
  80.     /**
  81.      * 既存のフィールドの定義にあるアノテーションの設定をXMLの定義で上書きするかどうか。
  82.      * <p>ただし、XMLに定義していないアノテーションは、既存のフィールドに定義にあるものを使用する。</p>
  83.      * @since 1.0
  84.      * @return true:XMLの定義で上書きする。
  85.      */
  86.     public boolean isOverride() {
  87.         return override;
  88.     }
  89.    
  90.     /**
  91.      * 既存のフィールドの定義にあるアノテーションの設定をXMLの定義で上書きするかどうか設定する。
  92.      * <p>ただし、XMLに定義していないアノテーションは、既存のフィールドに定義にあるものを使用する。</p>
  93.      * @since 1.0
  94.      * @param override true:XMLの定義で上書きする。
  95.      */
  96.     @XmlAttribute(name="override", required=false)
  97.     public void setOverride(final boolean override) {
  98.         this.override = override;
  99.     }
  100.    
  101.     /**
  102.      * アノテーション情報を追加する。
  103.      * <p>ただし、既に同じアノテーションが存在する場合は、それと入れ替えされます。</p>
  104.      * @param annotationInfo アノテーション情報。
  105.      * @throws IllegalArgumentException annotationInfo is null.
  106.      */
  107.     public void addAnnotationInfo(final AnnotationInfo annotationInfo) {
  108.         ArgUtils.notNull(annotationInfo, "annotationInfo");
  109.        
  110.         removeAnnotationInfo(annotationInfo.getClassName());
  111.         this.annotationInfos.add(annotationInfo);
  112.     }
  113.    
  114.     /**
  115.      * アノテーションのクラス名を指定してアノテーション情報を取得する。
  116.      * @param annotationClassName アノテーションのクラス名(FQCN)。
  117.      * @return 指定したクラスが存在しない場合は、nullを返す。
  118.      */
  119.     public AnnotationInfo getAnnotationInfo(final String annotationClassName) {
  120.         for(AnnotationInfo item : annotationInfos) {
  121.             if(item.getClassName().equals(annotationClassName)) {
  122.                 return item;
  123.             }
  124.         }
  125.        
  126.         return null;
  127.     }
  128.    
  129.     /**
  130.      * 指定したアノテーション情報を含むかどうか。
  131.      * @since 1.1
  132.      * @param annotationClassName アノテーションのクラス名(FQCN)。
  133.      * @return true:指定したクラスが存在する場合。
  134.      */
  135.     public boolean containsAnnotationInfo(final String annotationClassName) {
  136.         return getAnnotationInfo(annotationClassName) != null;
  137.     }
  138.    
  139.     /**
  140.      * 指定したアノテーション情報を削除します。
  141.      * @since 1.4.1
  142.      * @param annotationClassName アノテーションのクラス名(FQCN)。
  143.      * @return true:指定したアノテーション名を含み、それが削除できた場合。
  144.      */
  145.     public boolean removeAnnotationInfo(final String annotationClassName) {
  146.        
  147.         final AnnotationInfo existInfo = getAnnotationInfo(annotationClassName);
  148.         if(existInfo != null) {
  149.             this.annotationInfos.remove(existInfo);
  150.             return true;
  151.         }
  152.        
  153.         return false;
  154.        
  155.     }
  156.    
  157.     /**
  158.      * JAXB用のアノテーション情報を設定するメソッド。
  159.      * <p>XMLの読み込み時に呼ばれます。
  160.      *  <br>ただし、Java8からはこのメソッドは呼ばれず、{@link #getAnnotationInfos()} で取得したインスタンスに対して要素が追加されます。
  161.      * </p>
  162.      * <p>既存の情報はクリアされます。</p>
  163.      * @since 1.1
  164.      * @param annotationInfos アノテーション情報。
  165.      */
  166.     @XmlElement(name="annotation")
  167.     public void setAnnotationInfos(final List<AnnotationInfo> annotationInfos) {
  168.         if(annotationInfos == this.annotationInfos) {
  169.             // Java7の場合、getterで取得したインスタンスをそのまま設定するため、スキップする。
  170.             return;
  171.         }
  172.        
  173.         this.annotationInfos.clear();
  174.         for(AnnotationInfo item : annotationInfos) {
  175.             addAnnotationInfo(item);
  176.         }
  177.     }
  178.    
  179.     /**
  180.      * JAXB用のアノテーション情報を全て取得するメソッド。
  181.      * <p>XMLの書き込み時に呼ばれます。
  182.      *  <br>ただし、Java8から読み込み時に呼ばれるようになり、取得したインスタンスに対して、読み込んだ要素が追加されます。
  183.      * </p>
  184.      * @since 1.1
  185.      * @return アノテーション情報。
  186.      */
  187.     public List<AnnotationInfo> getAnnotationInfos() {
  188.         return this.annotationInfos;
  189.     }
  190.    
  191.     /**
  192.      * {@link FieldInfo}を組み立てるためのクラス。
  193.      *
  194.      */
  195.     public static final class Builder {
  196.        
  197.         private String fieldName;
  198.        
  199.         private boolean override;
  200.        
  201.         private List<AnnotationInfo> annotationInfos;
  202.        
  203.         private Builder() {
  204.             this.annotationInfos = new ArrayList<>();
  205.         }
  206.        
  207.         /**
  208.          * 組み立てた{@link FieldInfo}のインスタンスを取得する。
  209.          * @return
  210.          */
  211.         public FieldInfo buildField() {
  212.            
  213.             if(Utils.isEmpty(fieldName)) {
  214.                 throw new IllegalStateException("field name is required.");
  215.             }
  216.            
  217.             return new FieldInfo(this);
  218.         }
  219.        
  220.         /**
  221.          * フィールド名を設定する。
  222.          * @param fieldName フィールド名
  223.          * @return
  224.          * @throws IllegalArgumentException fieldName is empty.
  225.          */
  226.         public Builder name(final String fieldName) {
  227.             ArgUtils.notEmpty(fieldName, "fieldName");
  228.             this.fieldName = fieldName;
  229.             return this;
  230.         }
  231.        
  232.         /**
  233.          * 既存のフィールドに定義にあるアノテーションの設定をXMLの定義で上書きするかどうか設定する。
  234.          * @param override true:XMLの定義で上書きする。
  235.          * @return
  236.          */
  237.         public Builder override(final boolean override) {
  238.             this.override = override;
  239.             return this;
  240.         }
  241.        
  242.         /**
  243.          * フィールドに対するアノテーション情報を追加する。
  244.          * @param annotationInfo
  245.          * @return
  246.          * @throws IllegalArgumentException annotationInfo is null.
  247.          */
  248.         public Builder annotation(final AnnotationInfo annotationInfo) {
  249.             ArgUtils.notNull(annotationInfo, "annotationInfo");
  250.             this.annotationInfos.add(annotationInfo);
  251.             return this;
  252.         }
  253.        
  254.     }
  255.    

  256. }