ClassInfo.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.  * @version 1.1
  12.  * @since 0.5
  13.  * @author T.TSUCHIE
  14.  *
  15.  */
  16. public class ClassInfo implements Serializable {
  17.    
  18.     /** serialVersionUID */
  19.     private static final long serialVersionUID = 1L;
  20.    
  21.     private String className;
  22.    
  23.     private boolean override;
  24.    
  25.     private List<AnnotationInfo> annotationInfos = new ArrayList<>();
  26.    
  27.     private List<MethodInfo> methodInfos = new ArrayList<>();
  28.    
  29.     private List<FieldInfo> fieldInfos = new ArrayList<>();
  30.    
  31.     /**
  32.      * ビルダクラスのインスタンスを取得する。
  33.      * @since 1.1
  34.      * @return
  35.      */
  36.     public static Builder builder() {
  37.         return new Builder();
  38.     }
  39.    
  40.     public ClassInfo() {
  41.        
  42.     }
  43.    
  44.     private ClassInfo(final Builder builder) {
  45.         this.className = builder.className;
  46.         this.override = builder.override;
  47.         setAnnotationInfos(builder.annotationInfos);
  48.         setMethodInfos(builder.methodInfos);
  49.         setFieldInfos(builder.fieldInfos);
  50.     }
  51.    
  52.     @Override
  53.     public String toString() {
  54.         StringBuilder sb= new StringBuilder();
  55.        
  56.         sb.append("ClassInfo:")
  57.             .append(String.format(" [name=%s]", getClassName()))
  58.             .append(String.format(" [override=%b]", isOverride()));
  59.        
  60.         for(AnnotationInfo anno : annotationInfos) {
  61.             sb.append("  ").append(anno.toString());
  62.         }
  63.        
  64.         for(MethodInfo method : methodInfos) {
  65.             sb.append("  ").append(method.toString());
  66.         }
  67.        
  68.         for(FieldInfo field : fieldInfos) {
  69.             sb.append("  ").append(field.toString());
  70.         }
  71.        
  72.         return sb.toString();
  73.     }
  74.    
  75.     /**
  76.      * クラス名を取得する。
  77.      * @return FQCN(完全限定クラス名)を指定します。
  78.      */
  79.     public String getClassName() {
  80.         return className;
  81.     }
  82.    
  83.     /**
  84.      * クラス名を設定する。
  85.      * @param className FQCN(完全限定クラス名)を設定します。
  86.      * @throws IllegalArgumentException className is empty.
  87.      */
  88.     @XmlAttribute(name="name", required=true)
  89.     public void setClassName(final String className) {
  90.         ArgUtils.notEmpty(className, "className");
  91.         this.className = className;
  92.     }
  93.    
  94.     /**
  95.      * 既存のクラスの定義にあるアノテーションの設定をXMLの定義で上書きするかどうか。
  96.      * <p>ただし、XMLに定義していないアノテーションは、既存のクラスに定義にあるものを使用する。</p>
  97.      * @since 1.0
  98.      * @return true:XMLの定義で上書きする。
  99.      */
  100.     public boolean isOverride() {
  101.         return override;
  102.     }
  103.    
  104.     /**
  105.      * 既存のクラスの定義にあるアノテーションの設定をXMLの定義で上書きするかどうか設定する。
  106.      * <p>ただし、XMLに定義していないアノテーションは、既存のクラスに定義にあるものを使用する。
  107.      * @since 1.0
  108.      * @param override true:XMLの定義で上書きする。
  109.      */
  110.     @XmlAttribute(name="override", required=false)
  111.     public void setOverride(final boolean override) {
  112.         this.override = override;
  113.     }
  114.    
  115.     /**
  116.      * アノテーション情報を追加する。
  117.      * <p>ただし、既に同じアノテーションが存在する場合は、それと入れ替えされます。</p>
  118.      * @param annotationInfo アノテーション情報。
  119.      * @throws IllegalArgumentException annotationInfo is null.
  120.      */
  121.     public void addAnnotationInfo(final AnnotationInfo annotationInfo) {
  122.         ArgUtils.notNull(annotationInfo, "annotationInfo");
  123.        
  124.         removeAnnotationInfo(annotationInfo.getClassName());
  125.         this.annotationInfos.add(annotationInfo);
  126.     }
  127.    
  128.     /**
  129.      * アノテーションのクラス名を指定してアノテーション情報を取得する。
  130.      * @param annotationClassName アノテーションのクラス名(FQCN)。
  131.      * @return 指定したクラスが存在しない場合は、nullを返す。
  132.      */
  133.     public AnnotationInfo getAnnotationInfo(final String annotationClassName) {
  134.         for(AnnotationInfo item : annotationInfos) {
  135.             if(item.getClassName().equals( annotationClassName)) {
  136.                 return item;
  137.             }
  138.         }
  139.        
  140.         return null;
  141.     }
  142.    
  143.     /**
  144.      * 指定したアノテーション情報を含むかどうか。
  145.      * @since 1.1
  146.      * @param annotationClassName アノテーションのクラス名(FQCN)。
  147.      * @return true:指定したクラスが存在する場合。
  148.      */
  149.     public boolean containsAnnotationInfo(final String annotationClassName) {
  150.         return getAnnotationInfo(annotationClassName) != null;
  151.     }
  152.    
  153.     /**
  154.      * 指定したアノテーション情報を削除します。
  155.      * @since 1.4.1
  156.      * @param annotationClassName アノテーションのクラス名(FQCN)。
  157.      * @return true:指定したアノテーション名を含み、それが削除できた場合。
  158.      */
  159.     public boolean removeAnnotationInfo(final String annotationClassName) {
  160.        
  161.         final AnnotationInfo existInfo = getAnnotationInfo(annotationClassName);
  162.         if(existInfo != null) {
  163.             this.annotationInfos.remove(existInfo);
  164.             return true;
  165.         }
  166.        
  167.         return false;
  168.        
  169.     }
  170.    
  171.     /**
  172.      * メソッド情報を追加する。
  173.      * <p>ただし、既に同じメソッドが存在する場合は、それと入れ替えされます。</p>
  174.      * @param methodInfo メソッド情報。
  175.      * @throws IllegalArgumentException methodInfo is null.
  176.      */
  177.     public void addMethodInfo(final MethodInfo methodInfo) {
  178.         ArgUtils.notNull(methodInfo, "methodInfo");
  179.        
  180.         removeMethodInfo(methodInfo.getMethodName());
  181.         this.methodInfos.add(methodInfo);
  182.     }
  183.    
  184.     /**
  185.      * メソッド名を指定してメソッド情報を取得する。
  186.      * @param methodName メソッド名。
  187.      * @return 指定したメソッド名が存在しない場合は、nullを返す。
  188.      */
  189.     public MethodInfo getMethodInfo(final String methodName) {
  190.         for(MethodInfo item : methodInfos) {
  191.             if(item.getMethodName().equals(methodName)) {
  192.                 return item;
  193.             }
  194.         }
  195.        
  196.         return null;
  197.     }
  198.    
  199.     /**
  200.      * 指定したメソッド情報を含むかどうか。
  201.      * @param methodName メソッド名。
  202.      * @return true: 指定したメソッド名が存在する場合。
  203.      */
  204.     public boolean containsMethodInfo(final String methodName) {
  205.         return getMethodInfo(methodName) != null;
  206.     }
  207.    
  208.     /**
  209.      * 指定したメソッド情報を削除します。
  210.      * @since 1.4.1
  211.      * @param methodName メソッド名。
  212.      * @return true:指定したメソッド名を含み、それが削除できた場合。
  213.      */
  214.     public boolean removeMethodInfo(final String methodName) {
  215.        
  216.         final MethodInfo existInfo = getMethodInfo(methodName);
  217.         if(existInfo != null) {
  218.             this.methodInfos.remove(existInfo);
  219.             return true;
  220.         }
  221.        
  222.         return false;
  223.        
  224.     }
  225.    
  226.     /**
  227.      * フィールド情報を追加する。
  228.      * <p>ただし、既に同じフィールドが存在する場合は、それと入れ替えされます。</p>
  229.      * @param fieldInfo フィールド情報。
  230.      * @throws IllegalArgumentException fieldInfo is null.
  231.      */
  232.     public void addFieldInfo(final FieldInfo fieldInfo) {
  233.         ArgUtils.notNull(fieldInfo, "fieldInfo");
  234.        
  235.         removeFieldInfo(fieldInfo.getFieldName());
  236.         this.fieldInfos.add(fieldInfo);
  237.     }
  238.    
  239.     /**
  240.      * フィールド名を指定してフィールド情報を取得する。
  241.      * @param fieldName フィールド名。
  242.      * @return 指定したフィールド名が存在しない場合は、nullを返す。
  243.      */
  244.     public FieldInfo getFieldInfo(final String fieldName) {
  245.         for(FieldInfo item : fieldInfos) {
  246.             if(item.getFieldName().equals(fieldName)) {
  247.                 return item;
  248.             }
  249.         }
  250.        
  251.         return null;
  252.     }
  253.    
  254.     /**
  255.      * 指定したフィールド情報を含むかどうか。
  256.      * @param fieldName フィールド名。
  257.      * @return true: 指定したフィールド名が存在する場合。
  258.      */
  259.     public boolean containsFieldInfo(final String fieldName) {
  260.         return getFieldInfo(fieldName) != null;
  261.     }
  262.    
  263.     /**
  264.      * 指定したフィールド情報を削除します。
  265.      * @since 1.4.1
  266.      * @param fieldName フィールドのクラス名(FQCN)。
  267.      * @return true:指定したフィールド名を含み、それが削除できた場合。
  268.      */
  269.     public boolean removeFieldInfo(final String fieldName) {
  270.        
  271.         final FieldInfo existInfo = getFieldInfo(fieldName);
  272.         if(existInfo != null) {
  273.             this.fieldInfos.remove(existInfo);
  274.             return true;
  275.         }
  276.        
  277.         return false;
  278.        
  279.     }
  280.    
  281.     /**
  282.      * JAXB用のアノテーション情報を設定するメソッド。
  283.      * <p>XMLの読み込み時に呼ばれます。
  284.      *  <br>ただし、Java8からはこのメソッドは呼ばれず、{@link #getAnnotationInfos()} で取得したインスタンスに対して要素が追加されます。
  285.      * </p>
  286.      * <p>既存の情報はクリアされます。
  287.      * @since 1.1
  288.      * @param annotationInfos アノテーション情報。
  289.      */
  290.     @XmlElement(name="annotation")
  291.     public void setAnnotationInfos(final List<AnnotationInfo> annotationInfos) {
  292.        
  293.         if(annotationInfos == this.annotationInfos) {
  294.             // Java7の場合、getterで取得したインスタンスをそのまま設定するため、スキップする。
  295.             return;
  296.         }
  297.        
  298.         this.annotationInfos.clear();
  299.         for(AnnotationInfo item : annotationInfos) {
  300.             addAnnotationInfo(item);
  301.         }
  302.     }
  303.    
  304.     /**
  305.      * JAXB用のアノテーション情報を全て取得するメソッド。
  306.      * <p>XMLの書き込み時に呼ばれます。
  307.      *  <br>Java8から読み込み時に呼ばれるようになり、取得したインスタンスに対して、読み込んだ要素が呼ばれます。
  308.      * </p>
  309.      * @since 1.1
  310.      * @return アノテーション情報。
  311.      */
  312.     public List<AnnotationInfo> getAnnotationInfos() {
  313.         return annotationInfos;
  314.     }
  315.    
  316.     /**
  317.      * JAXB用のメソッド情報を設定するメソッド。
  318.      * <p>XMLの読み込み時に呼ばれます。
  319.      *  <br>ただし、Java8からはこのメソッドは呼ばれず、{@link #getMethodInfos()} で取得したインスタンスに対して要素が追加されます。
  320.      * </p>
  321.      * <p>既存の情報はクリアされます。</p>
  322.      * @since 1.1
  323.      * @param methodInfos メソッド情報。
  324.      */
  325.     @XmlElement(name="method")
  326.     public void setMethodInfos(final List<MethodInfo> methodInfos) {
  327.         if(methodInfos == this.methodInfos) {
  328.             // Java7の場合、getterで取得したインスタンスをそのまま設定するため、スキップする。
  329.             return;
  330.         }
  331.        
  332.         this.methodInfos.clear();
  333.         for(MethodInfo item : methodInfos) {
  334.             addMethodInfo(item);
  335.         }
  336.     }
  337.    
  338.     /**
  339.      * JAXB用のメソッド情報を全て取得するメソッド。
  340.      * <p>XMLの書き込み時に呼ばれます。
  341.      *  <br>Java8から読み込み時に呼ばれるようになり、取得したインスタンスに対して、読み込んだ要素が呼ばれます。
  342.      * </p>
  343.      * @since 1.1
  344.      * @return メソッド情報。
  345.      */
  346.     public List<MethodInfo> getMethodInfos() {
  347.         return methodInfos;
  348.     }
  349.    
  350.     /**
  351.      * JAXB用のフィールド情報を設定するメソッド。
  352.      * <p>XMLの読み込み時に呼ばれます。
  353.      *  <br>ただし、Java8からはこのメソッドは呼ばれず、{@link #getFieldInfos()} で取得したインスタンスに対して要素が追加されます。
  354.      * </p>
  355.      * <p>既存の情報はクリアされます。</p>
  356.      * @since 1.1
  357.      * @param fieldInfos フィールド情報。
  358.      */
  359.     @XmlElement(name="field")
  360.     public void setFieldInfos(final List<FieldInfo> fieldInfos) {
  361.         if(fieldInfos == this.fieldInfos) {
  362.             // Java7の場合、getterで取得したインスタンスをそのまま設定するため、スキップする。
  363.             return;
  364.         }
  365.        
  366.         this.fieldInfos.clear();
  367.         for(FieldInfo item : fieldInfos) {
  368.             addFieldInfo(item);
  369.         }
  370.     }
  371.    
  372.     /**
  373.      * JAXB用のフィールド情報を全て取得するメソッド。
  374.      * <p>XMLの書き込み時に呼ばれます。
  375.      *  <br>Java8から読み込み時に呼ばれるようになり、取得したインスタンスに対して、読み込んだ要素が呼ばれます。
  376.      * </p>
  377.      * @since 1.1
  378.      * @return フィールド情報。
  379.      */
  380.     public List<FieldInfo> getFieldInfos() {
  381.         return fieldInfos;
  382.     }
  383.    
  384.     /**
  385.      * {@link ClassInfo}を組み立てるためのクラス。
  386.      *
  387.      */
  388.     public static final class Builder {
  389.        
  390.         private String className;
  391.        
  392.         private boolean override;
  393.        
  394.         private List<AnnotationInfo> annotationInfos;
  395.        
  396.         private List<MethodInfo> methodInfos;
  397.        
  398.         private List<FieldInfo> fieldInfos;
  399.        
  400.         private Builder() {
  401.             this.annotationInfos = new ArrayList<>();
  402.             this.methodInfos = new ArrayList<>();
  403.             this.fieldInfos = new ArrayList<>();
  404.         }
  405.        
  406.         /**
  407.          * 組み立てた{@link ClassInfo}のインスタンスを取得する。
  408.          * @return
  409.          */
  410.         public ClassInfo buildClass() {
  411.            
  412.             if(Utils.isEmpty(className)) {
  413.                 throw new IllegalStateException("class name is required.");
  414.             }
  415.            
  416.             return new ClassInfo(this);
  417.         }
  418.        
  419.         /**
  420.          * クラス名を設定する。
  421.          * @param className クラス名。FQCN(完全限定クラス名)を設定します。
  422.          * @return
  423.          * @throws IllegalArgumentException calssName is empty.
  424.          */
  425.         public Builder name(final String className) {
  426.             ArgUtils.notEmpty(className, "className");
  427.             this.className = className;
  428.             return this;
  429.         }
  430.        
  431.         /**
  432.          * クラス名を設定する。
  433.          * @param clazz クラス情報。
  434.          * @return
  435.          * @throws IllegalArgumentException clazz is null.
  436.          */
  437.         public Builder name(final Class<?> clazz) {
  438.             ArgUtils.notNull(clazz, "clazz");
  439.             return name(clazz.getName());
  440.            
  441.         }
  442.        
  443.         /**
  444.          * 既存のクラスの定義にあるアノテーションの設定をXMLの定義で上書きするかどうか設定する。
  445.          * @param override true:XMLの定義で上書きする。
  446.          * @return
  447.          */
  448.         public Builder override(final boolean override) {
  449.             this.override = override;
  450.             return this;
  451.         }
  452.        
  453.         /**
  454.          * クラスに対するアノテーション情報を追加する。
  455.          * @param annotationInfo アノテーション情報
  456.          * @return
  457.          * @throws IllegalArgumentException annotationInfo is null.
  458.          */
  459.         public Builder annotation(final AnnotationInfo annotationInfo) {
  460.             ArgUtils.notNull(annotationInfo, "annotationInfo");
  461.             this.annotationInfos.add(annotationInfo);
  462.             return this;
  463.         }
  464.        
  465.         /**
  466.          * メソッド情報を追加する。
  467.          * @param methodInfo メソッド情報
  468.          * @return
  469.          * @throws IllegalArgumentException methodInfo is null.
  470.          */
  471.         public Builder method(final MethodInfo methodInfo) {
  472.             ArgUtils.notNull(methodInfo, "methodInfo");
  473.             this.methodInfos.add(methodInfo);
  474.             return this;
  475.         }
  476.        
  477.         /**
  478.          * フィールド情報を追加する。
  479.          * @param fieldInfo フィールド情報。
  480.          * @return
  481.          * @throws IllegalArgumentException fieldInfo is null.
  482.          */
  483.         public Builder field(final FieldInfo fieldInfo) {
  484.             ArgUtils.notNull(fieldInfo, "fieldInfo");
  485.             this.fieldInfos.add(fieldInfo);
  486.             return this;
  487.         }
  488.        
  489.     }
  490. }