Utils.java

  1. package com.github.mygreen.supercsv.util;

  2. import java.lang.annotation.Annotation;
  3. import java.lang.reflect.Method;
  4. import java.util.Collection;
  5. import java.util.Locale;
  6. import java.util.Map;
  7. import java.util.Objects;
  8. import java.util.Optional;

  9. import com.github.mygreen.supercsv.annotation.PatternFlag;
  10. import com.github.mygreen.supercsv.builder.BuildCase;


  11. /**
  12.  * ユーティリティクラス。
  13.  *
  14.  * @version 2.2
  15.  * @author T.TSUCHIE
  16.  *
  17.  */
  18. public class Utils {
  19.    
  20.     /**
  21.      * <a href="http://www.joda.org/joda-time/" target="_blank">Joda-Time</a>のライブラリが利用可能かどうか。
  22.      */
  23.     public static final boolean ENABLED_LIB_JODA_TIME;
  24.     static {
  25.         boolean enabled;
  26.         try {
  27.             Class.forName("org.joda.time.LocalDateTime");
  28.             enabled = true;
  29.         } catch(ClassNotFoundException e) {
  30.             enabled = false;
  31.         }
  32.         ENABLED_LIB_JODA_TIME = enabled;
  33.     }
  34.    
  35.     /**
  36.      * 文字列が空文字か判定する。
  37.      * @param str
  38.      * @return
  39.      */
  40.     public static boolean isEmpty(final String str) {
  41.         if(str == null || str.isEmpty()) {
  42.             return true;
  43.         }
  44.        
  45.         if(str.length() == 1) {
  46.             return str.charAt(0) == '\u0000';
  47.         }
  48.        
  49.         return false;
  50.     }
  51.    
  52.     /**
  53.      * 文字列が空文字でないか判定する。
  54.      * @param str
  55.      * @return
  56.      */
  57.     public static boolean isNotEmpty(final String str) {
  58.         return !isEmpty(str);
  59.     }
  60.    
  61.     /**
  62.      * コレクションが空か判定する。
  63.      * @param collection
  64.      * @return nullまたはサイズが0のときにtrueを返す。
  65.      */
  66.     public static boolean isEmpty(final Collection<?> collection) {
  67.         if(collection == null || collection.isEmpty()) {
  68.             return true;
  69.         }
  70.        
  71.         return false;
  72.     }
  73.    
  74.     public static boolean isNotEmpty(final Collection<?> collection) {
  75.         return !isEmpty(collection);
  76.     }
  77.    
  78.     /**
  79.      * Mapが空か判定する。
  80.      * @param map
  81.      * @return nullまたはサイズが0のときにtrueを返す。
  82.      */
  83.     public static boolean isEmpty(final Map<?, ?> map) {
  84.         if(map == null || map.isEmpty()) {
  85.             return true;
  86.         }
  87.        
  88.         return false;
  89.     }
  90.    
  91.     public static boolean isNotEmpty(final Map<?, ?> map) {
  92.         return !isEmpty(map);
  93.     }
  94.    
  95.     /**
  96.      * 配列がが空か判定する。
  97.      * @param arrays
  98.      * @return nullまたは、配列のサイズが0のときにtrueを返す。
  99.      */
  100.     public static boolean isEmpty(final Object[] arrays) {
  101.         if(arrays == null || arrays.length == 0) {
  102.             return true;
  103.         }
  104.        
  105.         return false;
  106.     }
  107.    
  108.     /**
  109.      * 配列が空でないか判定する
  110.      * @param arrays
  111.      * @return
  112.      */
  113.     public static boolean isNotEmpty(final Object[] arrays) {
  114.         return !isEmpty(arrays);
  115.     }
  116.    
  117.     /**
  118.      * 文字列形式のロケールをオブジェクトに変換する。
  119.      * <p>アンダーバーで区切った'ja_JP'を分解して、Localeに渡す。
  120.      * @since 1.2
  121.      * @param str
  122.      * @return 引数が空の時はデフォルトロケールを返す。
  123.      */
  124.     public static Locale getLocale(final String str) {
  125.        
  126.         if(isEmpty(str)) {
  127.             return Locale.getDefault();
  128.         }
  129.        
  130.         if(!str.contains("_")) {
  131.             return new Locale(str);
  132.         }
  133.        
  134.         final String[] split = str.split("_");
  135.         if(split.length == 2) {
  136.             return new Locale(split[0], split[1]);
  137.            
  138.         } else {
  139.             return new Locale(split[0], split[1], split[2]);
  140.         }
  141.        
  142.     }
  143.    
  144.     /**
  145.      * アノテーションの指定した属性値を取得する。
  146.      * <p>アノテーションの修飾子はpublicである必要があります。</p>
  147.      * @param anno アノテーションのインスタンス
  148.      * @param attrName 属性名
  149.      * @param attrType 属性のタイプ。
  150.      * @return 属性を持たない場合、空を返す。
  151.      */
  152.     @SuppressWarnings("unchecked")
  153.     public static <T> Optional<T> getAnnotationAttribute(final Annotation anno, final String attrName, final Class<T> attrType) {
  154.        
  155.         try {
  156.             final Method method = anno.annotationType().getMethod(attrName);
  157.             method.setAccessible(true);
  158.             if(!attrType.equals(method.getReturnType())) {
  159.                 return Optional.empty();
  160.             }
  161.            
  162.             final Object value = method.invoke(anno);
  163.             return Optional.of((T)value);
  164.            
  165.         } catch (Exception e) {
  166.             return Optional.empty();
  167.         }
  168.        
  169.     }
  170.    
  171.     /**
  172.      * アノテーションの指定した属性値を持つかどうか判定する。
  173.      * <p>アノテーションの修飾子はpublicである必要があります。</p>
  174.      * @param anno アノテーションのインスタンス
  175.      * @param attrName 属性名
  176.      * @param attrType 属性のタイプ。
  177.      * @return 属性を持つ場合trueを返す。
  178.      */
  179.     public static <T>  boolean hasAnnotationAttribute(final Annotation anno, final String attrName, final Class<T> attrType) {
  180.        
  181.         return getAnnotationAttribute(anno, attrName, attrType).isPresent();
  182.        
  183.     }
  184.    
  185.     /**
  186.      * アノテーションの属性「cases」を持つ場合、指定した種類を持つか判定する。
  187.      * <p>属性「buildCase」を持たない場合、または、空の配列の場合は、必ずtrueを返します。</p>
  188.      *
  189.      * @param anno 判定対象のアノテーション。
  190.      * @param buildCase 組み立てる種類。
  191.      * @return trueの場合、指定した種類を含みます。
  192.      * @throws NullPointerException anno or buildCase is null.
  193.      */
  194.     public static boolean containsBuildCase(final Annotation anno, final BuildCase buildCase) {
  195.        
  196.         Objects.requireNonNull(anno);
  197.         Objects.requireNonNull(buildCase);
  198.        
  199.         final Optional<BuildCase[]> attrCases = getAnnotationAttribute(anno, "cases", BuildCase[].class);
  200.         if(attrCases.isPresent()) {
  201.             final BuildCase[] casesValue = attrCases.get();
  202.             if(casesValue.length == 0) {
  203.                 // 値が空の配列の場合
  204.                 return true;
  205.             }
  206.            
  207.             for(BuildCase value : casesValue) {
  208.                 if(value == buildCase) {
  209.                     return true;
  210.                 }
  211.             }
  212.            
  213.             return false;
  214.         }
  215.        
  216.         // 属性を持たない場合
  217.         return true;
  218.     }
  219.    
  220.     /**
  221.      * <a href="http://www.joda.org/joda-time/" target="_blank">Joda-Time</a>のライブラリが利用可能かどうか。
  222.      * @return {@literal true}利用可能。
  223.      */
  224.     public static boolean isEnabledJodaTime() {
  225.         return ENABLED_LIB_JODA_TIME;
  226.     }
  227.    
  228.     /**
  229.      * プリミティブ型の初期値を取得する。
  230.      * @param type プリミティブ型のクラス型。
  231.      * @return 非プリミティブ型や該当するクラスがない場合はnullを返す。
  232.      * @throws NullPointerException type is null.
  233.      */
  234.     public static Object getPrimitiveDefaultValue(final Class<?> type) {
  235.        
  236.         Objects.requireNonNull(type, "type should not be null.");
  237.        
  238.         if(!type.isPrimitive()) {
  239.             return null;
  240.            
  241.         } else if(boolean.class.isAssignableFrom(type)) {
  242.             return false;
  243.            
  244.         } else if(char.class.isAssignableFrom(type)) {
  245.             return '\u0000';
  246.            
  247.         } else if(byte.class.isAssignableFrom(type)) {
  248.             return (byte)0;
  249.            
  250.         } else if(short.class.isAssignableFrom(type)) {
  251.             return (short)0;
  252.            
  253.         } else if(int.class.isAssignableFrom(type)) {
  254.             return 0;
  255.            
  256.         } else if(long.class.isAssignableFrom(type)) {
  257.             return 0l;
  258.            
  259.         } else if(float.class.isAssignableFrom(type)) {
  260.             return 0.0f;
  261.            
  262.         } else if(double.class.isAssignableFrom(type)) {
  263.             return 0.0d;
  264.         }
  265.        
  266.         return null;
  267.        
  268.     }
  269.    
  270.     /**
  271.      * 文字列配列の結合
  272.      * @param array1
  273.      * @param array2
  274.      * @return 結合した配列。引数のどちらからnullの場合は、cloneした配列を返します。
  275.      */
  276.     public static String[] concat(final String[] array1, final String[] array2) {
  277.        
  278.         if(array1 == null || array1.length == 0) {
  279.             return clone(array2);
  280.            
  281.         } else if(array2 == null || array2.length == 0) {
  282.             return clone(array1);
  283.         }
  284.        
  285.         final String[] joinedArray = new String[array1.length + array2.length];
  286.         System.arraycopy(array1, 0, joinedArray, 0, array1.length);
  287.         System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
  288.         return joinedArray;
  289.        
  290.     }
  291.    
  292.     /**
  293.      * 文字列の配列をクローンします。
  294.      * @since 2.2
  295.      * @param array クローン対象の配列
  296.      * @return クローンした配列。引数がnullの場合は、nullを返します。
  297.      */
  298.     public static String[] clone(final String[] array) {
  299.         if (array == null) {
  300.             return null;
  301.         }
  302.         return array.clone();
  303.     }
  304.    
  305.     /**
  306.      * コレクションを配列に変換する。
  307.      * @param collection 変換対象のコレクション。
  308.      * @return 変換した配列。
  309.      * @throws NullPointerException collection is null.
  310.      */
  311.     public static int[] toArray(final Collection<Integer> collection) {
  312.         Objects.requireNonNull(collection);
  313.        
  314.         final int size = collection.size();
  315.         final int[] array = new int[size];
  316.        
  317.         int i=0;
  318.         for(Integer value : collection) {
  319.             array[i] = value;
  320.             i++;
  321.         }
  322.        
  323.         return array;
  324.     }
  325.    
  326.     /**
  327.      * 正規表現のフラグを組み立てる。
  328.      * @param flags 正規表現の列挙型のフラグ
  329.      * @return
  330.      */
  331.     public static int buildRegexFlags(final PatternFlag[] flags) {
  332.        
  333.         int intFlag = 0;
  334.         for(PatternFlag flag : flags) {
  335.             intFlag = intFlag | flag.getValue();
  336.         }
  337.        
  338.         return intFlag;
  339.        
  340.     }
  341.    
  342.     /**
  343.      * 先頭の文字を小文字にする。
  344.      * @param str
  345.      * @return 引数がnull、空文字の場合、そのまま返す。
  346.      */
  347.     public static String uncapitalize(final String str) {
  348.         final int strLen;
  349.         if(str == null || (strLen = str.length()) == 0) {
  350.             return str;
  351.         }
  352.        
  353.         return new StringBuilder(strLen)
  354.             .append(String.valueOf(str.charAt(0)).toLowerCase())
  355.             .append(str.substring(1))
  356.             .toString();
  357.     }
  358.    
  359.     /**
  360.      * 文字列をトリムする。
  361.      * @param value トリム対象の文字
  362.      * @param trimmed トリムするかどうか。
  363.      * @return トリミングした結果。
  364.      */
  365.     public static String trim(final String value, final boolean trimmed) {
  366.         if(!trimmed || value == null) {
  367.             return value;
  368.         }

  369.         return value.trim();

  370.     }
  371.    
  372.     /**
  373.      * 文字列をbooleanに変換します。
  374.      *
  375.      * @param value 変換対象の値。
  376.      * @param defaultValue 変換対象がnull or 空文字の時のデフォルト値。
  377.      * @return 引数がnullのとき、falseを返します。
  378.      */
  379.     public static boolean toBoolean(final String value, final boolean defaultValue) {
  380.         String text = trim(value, true);
  381.         if(isEmpty(text)) {
  382.             return defaultValue;
  383.         }
  384.        
  385.         return Boolean.valueOf(text.toLowerCase());
  386.     }
  387.    
  388. }