001/* 002 * Copyright (c) 2017 The openGion Project. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 013 * either express or implied. See the License for the specific language 014 * governing permissions and limitations under the License. 015 */ 016package org.opengion.fukurou.fileexec; 017 018import java.util.Locale; 019import java.util.Date; 020import java.text.DateFormat; 021import java.text.SimpleDateFormat; 022 023/** 024 * StringUtilは、共通的に使用される文字列処理に関する、ユーティリティークラスです。 025 * 026 * @og.rev 7.0.0.0 (2017/07/07) 新規作成 027 * 028 * @version 7.0 029 * @author Kazuhiko Hasegawa 030 * @since JDK1.8, 031 */ 032public final class StringUtil { 033 034 /** 035 * デフォルトコンストラクターをprivateにして、 036 * オブジェクトの生成をさせないようにする。 037 */ 038 private StringUtil() {} 039 040 /** 041 * 指定の文字列が nullか、ゼロ文字列 の場合は、2番目以降の引数から、null でない最初の値を返します。 042 * 2番目以降の引数には、ゼロ文字列の指定も可能です。 043 * 044 * @param val 判定する文字列 045 * @param def 初期値の可変長引数 046 * @return 指定の値で、最初にnullでない値。最後まで、無ければ、val を返します。 047 */ 048 public static String nval( final String val , final String... def ) { 049 if( val == null || val.trim().isEmpty() ) { 050 for( final String str : def ) { 051 if( str != null ) { return str.trim(); } // ゼロ文字列 の場合も、返します。 052 } 053 } 054 055 return val; // 最後まで null以外の値が見つからない場合なので、val が null の場合もありうる。 056 } 057 058 /** 059 * 指定の数値型文字列が nullか、ゼロ文字列 の場合は、2番目の初期値を返します。 060 * 061 * そうでない場合は、指定の文字列を、Integer.parseInt( String ) した値を返します。 062 * 063 * @param val 判定する数値型文字列 064 * @param def 初期値の数値 065 * @return 指定の文字列が nullか、ゼロ文字列でない場合は、数値に変換し、そうでなければ、初期値の数値を返します。 066 * @throws NumberFormatException 文字列が解析可能な整数型を含まない場合。 067 */ 068 public static int nval( final String val , final int def ) { 069 return val == null || val.trim().isEmpty() ? def : Integer.parseInt( val.trim() ); 070 } 071 072 /** 073 * LOGファイルのフォーマットに対応した日付、時刻文字列を作成します。 074 * 075 * yyyyMMddHHmmss 形式のフォーマットで、返します。 076 * 077 * @return 現在の日付、時刻文字列 078 */ 079 public static String getTimeFormat() { 080 return getTimeFormat( "yyyyMMddHHmmss" ); 081 } 082 083 /** 084 * 指定のフォーマットに対応した日付、時刻文字列を作成します。 085 * 086 * 例えば、LOGフォーマットの場合は、yyyyMMdd HH:mm:ss 形式です。 087 * 088 * @param format 日付、時刻文字列のフォーマット 089 * @return 指定のフォーマットに対応した現在の日付、時刻文字列 090 */ 091 public static String getTimeFormat( final String format ) { 092 final DateFormat formatter = new SimpleDateFormat( format , Locale.getDefault() ); 093 return formatter.format( new Date() ); 094 } 095 096 /** 097 * 指定のフォーマットに対応した日付、時刻文字列を作成します。 098 * 099 * 例えば、LOGフォーマットの場合は、yyyyMMdd HH:mm:ss 形式です。 100 * 101 * @param date フォーマットする日付情報 102 * @param format 日付、時刻文字列のフォーマット 103 * @return 指定のフォーマットに対応した指定の日付、時刻文字列 104 */ 105 public static String getTimeFormat( final long date , final String format ) { 106 final DateFormat formatter = new SimpleDateFormat( format , Locale.getDefault() ); 107 return formatter.format( new Date( date ) ); 108 } 109 110 /** 111 * EUROMAPの日付、時間文字列から、openGion系日付時刻文字列を作成します。 112 * 113 * 日付は、yyyyMMdd 形式で、時間は、HH:mm:ss 形式を標準としますが、 114 * 数字以外の文字列を削除して、連結した文字列を作成します。 115 * その場合、14桁数字文字列 になります。 116 * 117 * その形式に合わない場合は、現在時刻 を返します。 118 * ただし、日付の整合性チェックは、行っていません。 119 * 120 * @param ymd EUROMAPの日付(yyyyMMdd形式の8桁数字) 121 * @param hms EUROMAPの時間(HH:mm:ss形式の8桁数字) 122 * @return openGion系日付時刻文字列(yyyyMMddHHmmss形式の14桁数字) 123 */ 124 public static String getTime( final String ymd , final String hms ) { 125 if( ymd != null && hms != null ) { 126 if( ymd.length() == 8 && hms.length() == 8 ) { 127 return ymd + hms.substring(0,2) + hms.substring(3,5) + hms.substring(6); 128 } 129 else { 130 final StringBuilder buf = new StringBuilder(); 131 for( int i=0; i<ymd.length(); i++ ) { 132 final char ch = ymd.charAt( i ); 133 if( '0' <= ch && ch < '9' ) { buf.append( ch ); } // 数字のみ許可 134 } 135 136 for( int i=0; i<hms.length(); i++ ) { 137 final char ch = hms.charAt( i ); 138 if( '0' <= ch && ch < '9' ) { buf.append( ch ); } // 数字のみ許可 139 } 140 141 if( buf.length() == 14 ) { 142 return buf.toString(); 143 } 144 } 145 } 146 147 // 引数が存在しない場合は、無条件に1秒待ちます。 148 // これは、テスト用に日付無しのDATデータを用意して登録する場合に使用します。 149 try{ Thread.sleep( 1000 ); } catch( final InterruptedException ex ){} 150 151 return getTimeFormat() ; // 現在時刻 152 } 153 154 /** 155 * すべての引数をスペースで連結してtrim()した文字列を返します。 156 * 157 * 各引数は、それぞれ、trim()した後、スペースで連結します。 158 * ただし、引数が、nullの場合は、ゼロ文字列に変換します。 159 * すべてを連結して、trim() した結果が、ゼロ文字列の場合は、defVal を返します。 160 * 161 * @param defVal 結果が、ゼロ文字列の場合に返す文字列 162 * @param keys 連結したいキーの可変長文字列配列 163 * @return 合成した文字列。 164 */ 165 public static String keyAppend( final String defVal , final String... keys ) { 166 final StringBuilder buf = new StringBuilder(); 167 for( final String key : keys ) { 168 buf.append( nval( key , "" ).trim() ).append( ' ' ); 169 } 170 171 return nval( buf.toString().trim() , defVal ); 172 } 173 174 /** 175 * 指定の文字列を、引数の文字で、前後に分割します。 176 * キー=値 や、キー,値 などの文字列を分割して、キーと値の配列を返します。 177 * 1番目の配列[0] は、キー(chの左側)、2番目の配列[1] は、値(chの右側) です。 178 * キーも値も、前後のスペースを削除:trim() します。 179 * キー(1番目の配列[0])は、空文字列を許可しません。 180 * 181 * 分割文字を含まない場合や、キーが、空文字列の場合は、null を返します。 182 * nullで無い場合は、配列は、必ず2個存在しそのどちらの値も、null を含みません。 183 * 184 * @param line 1行分の文字列 185 * @param ch 分割する文字 186 * @return キーと値の配列。無ければ、null 187 */ 188 public static String[] split( final String line , final char ch ) { 189 final int ad = line.indexOf( ch ); 190 if( ad > 0 ) { // ch が先頭は無視 191 final String key = line.substring( 0,ad ).trim(); 192 193 if( !key.isEmpty() ) { 194 final String val = line.substring( ad+1 ).trim(); 195 return new String[] { key , val }; 196 } 197 } 198 return null; 199 } 200 201 /** 202 * 数字型文字列の一致をチェックします。 203 * 204 * 処理としては、数字型文字列以外を判定条件に入れても、同一文字列の場合は、 205 * true になります。 206 * ここでは、どちらかの文字列の末尾が、".0" などの場合に、同じかどうかを 207 * 数値に変換して、判定します。 208 * どちらかが、null の場合は、必ず false になります。両方とも、null でも false です。 209 * 210 * @param val1 判定用の引数1 211 * @param val2 判定用の引数2 212 * @return 判定結果(一致する場合は、true) 213 */ 214 public static boolean numEquals( final String val1 , final String val2 ) { 215 if( val1 == null || val2 == null ) { return false; } 216 217 if( val1.equals( val2 ) ) { 218 return true; 219 } 220 else { 221 try { 222 return Double.parseDouble( val1 ) == Double.parseDouble( val2 ); 223 } 224 catch( final NumberFormatException ex ) { 225 // 数値変換できなかった場合は、無視します。 226 } 227 } 228 229 return false; 230 } 231}