001/* 002 * Copyright (c) 2009 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.db; 017 018import java.io.UnsupportedEncodingException; 019import java.util.Calendar ; // 7.0.5.0 (2019/09/16) 020 021import org.opengion.fukurou.util.StringUtil; // 6.9.8.0 (2018/05/28) 022import org.opengion.fukurou.util.HybsDateUtil; // 7.0.5.0 (2019/09/16) 023 024/** 025 * JavaDB(derby) や、hsqldb に対する、Javaの拡張組込み関数です。 026 * 027 * staticメソッドとして、関数を定義します。引数や返り値は、各データベースの 028 * 定義に準拠します。 029 * 030 * <pre> 031 * ① JavaDB の場合 032 * 【概要】 033 * 実行するデータベースから見えるところに、ファイルを配置する必要があります。 034 * java8 までなら、Javaのエクステンション(JAVA_HOME\)jre\lib\ext などですが、 035 * java9以降は、CLASSPATH に設定します。 036 * openGionでは、bin/const.bat で、OG_CLASSPATH 環境変数にパスを通して、 037 * 使用しています。 038 * 標準の Java staticメソッドを FUNCTION 定義することも出来ます。 039 * 【設定】 040 * JavaDBに FUNCTION を定義します。(サンプル) 041 * DROP FUNCTION TO_CHAR; 042 * 043 * CREATE FUNCTION TO_CHAR ( VAL DOUBLE ) 044 * RETURNS VARCHAR(20) 045 * DETERMINISTIC -- 引数が同じなら常に同じ値を返すことを示す.(省略時はnot deterministic) 046 * PARAMETER STYLE JAVA -- 戻り値のタイプ 047 * NO SQL LANGUAGE JAVA -- 関数の中でSQLは実行しないことを示す 048 * EXTERNAL NAME 'org.opengion.fukurou.db.Functions.toChar' ; 049 * 050 * ② HSQLDB の場合 051 * 【概要】 052 * 053 * </pre> 054 * 055 * @og.rev 6.8.5.1 (2018/01/15) org.opengion.javadb → org.opengion.fukurou.db にパッケージ変更 056 * @og.group 拡張組込み関数 057 * 058 * @version 1.1.0 059 * @author Kazuhiko Hasegawa 060 * @since JDK8.0, 061 */ 062public final class Functions { 063 private static final String ENCODE = "UTF-8"; 064 065 /** 066 * デフォルトコンストラクターをprivateにして、 067 * オブジェクトの生成をさせないようにする。 068 * 069 * @og.rev 6.9.7.0 (2018/05/14) 新規作成 070 */ 071 private Functions() {} 072 073 /** 074 * 数値を文字列に変換します。 075 * 076 * この関数は、引数の double が、小数点を含まない場合は、 077 * 小数点以下を出しません。 078 * JavaDBの場合、数字と文字列の連結が出来ないため、文字列変換関数を用意します。 079 * 080 * DROP FUNCTION TO_CHAR; 081 * 082 * CREATE FUNCTION TO_CHAR ( VAL DOUBLE ) 083 * RETURNS VARCHAR(20) 084 * DETERMINISTIC -- 引数が同じなら常に同じ値を返すことを示す.(省略時はnot deterministic) 085 * PARAMETER STYLE JAVA -- 戻り値のタイプ 086 * NO SQL LANGUAGE JAVA -- 関数の中でSQLは実行しないことを示す 087 * EXTERNAL NAME 'org.opengion.fukurou.db.Functions.toChar' ; 088 * 089 * @og.rev 6.7.3.0 (2017/01/27) 新規作成 090 * @og.rev 6.8.5.1 (2018/01/15) org.opengion.javadb → org.opengion.fukurou.db にパッケージ変更 091 * @og.rev 6.9.8.0 (2018/05/28) FindBugs:浮動小数点の等価性のためのテスト 092 * 093 * @param val 文字列に変換すべき数値 094 * @return 変換した文字列 095 */ 096 public static String toChar( final double val ) { 097 // 6.9.8.0 (2018/05/28) FindBugs の警告を避ける方法が、見つかりませんでした。 098 return val == (int)val ? String.valueOf( (int)val ) : String.valueOf( val ); 099 100// final int intVal = (int)val; 101// return ((double)intVal) == val ? String.valueOf( intVal ) : String.valueOf( val ); 102 } 103 104 /** 105 * 特殊な文字列の連結を行います。 106 * 107 * これは、第1引数の数字と、第2、第3、第4の文字列をスペースで連結した文字列を返します。 108 * 引数の個数が、可変に出来ないため、完全に決め打ちです。 109 * 110 * DROP FUNCTION JOIN2; 111 * 112 * CREATE FUNCTION JOIN2 ( INTEGER , VARCHAR(2000) , VARCHAR(2000) , VARCHAR(2000) ) 113 * RETURNS VARCHAR(4000) 114 * DETERMINISTIC -- 引数が同じなら常に同じ値を返すことを示す.(省略時はnot deterministic) 115 * PARAMETER STYLE JAVA -- 戻り値のタイプ 116 * NO SQL LANGUAGE JAVA -- 関数の中でSQLは実行しないことを示す 117 * EXTERNAL NAME 'org.opengion.fukurou.db.Functions.join2' ; 118 * 119 * @og.rev 6.7.3.0 (2017/01/27) 新規作成 120 * @og.rev 6.8.5.1 (2018/01/15) org.opengion.javadb → org.opengion.fukurou.db にパッケージ変更 121 * 122 * @param no 第1引数の数字 123 * @param arg2 第2引数 124 * @param arg3 第3引数 125 * @param arg4 第4引数 126 * @return 連結したした文字列 127 */ 128 public static String join2( final int no , final String arg2 , final String arg3 , final String arg4 ) { 129 return new StringBuilder() 130 .append( no ).append( ' ' ) 131 .append( arg2 == null ? "" : arg2 ).append( ' ' ) 132 .append( arg3 == null ? "" : arg3 ).append( ' ' ) 133 .append( arg4 == null ? "" : arg4 ).append( ' ' ) 134 .toString() ; 135 } 136 137 /** 138 * 対象の文字列の部分文字列を置換します。 139 * 140 * ただし、source、target、replacement のどれかが、null(ゼロ文字列)の場合は、 141 * 処理を実行せず、source をそのまま返します。 142 * 143 * DROP FUNCTION REPLACE; 144 * 145 * CREATE FUNCTION REPLACE ( VARCHAR(2000) , VARCHAR(2000) , VARCHAR(2000) ) 146 * RETURNS VARCHAR(4000) 147 * DETERMINISTIC -- 引数が同じなら常に同じ値を返すことを示す.(省略時はnot deterministic) 148 * PARAMETER STYLE JAVA -- 戻り値のタイプ 149 * NO SQL LANGUAGE JAVA -- 関数の中でSQLは実行しないことを示す 150 * EXTERNAL NAME 'org.opengion.fukurou.db.Functions.replace' ; 151 * 152 * @og.rev 6.7.3.0 (2017/01/27) 新規作成 153 * @og.rev 6.8.5.1 (2018/01/15) org.opengion.javadb → org.opengion.fukurou.db にパッケージ変更 154 * @og.rev 6.9.8.0 (2018/05/28) source、target、replacement のどれかが、null(ゼロ文字列)の場合は、source を返す。 155 * 156 * @param source 対象の文字列 157 * @param target 置換したい文字列 158 * @param replacement 置換する文字列 159 * @return 置換した文字列。 160 */ 161 public static String replace( final String source , final String target , final String replacement ) { 162 // 6.9.8.0 (2018/05/28) source、target、replacement のどれかが、null(ゼロ文字列)の場合は、source を返す。 163 if( StringUtil.isEmpty( source , target , replacement ) ) { // 一つでも、null の場合、true 164 return source; 165 } 166 else { 167 return source.replace( target,replacement ); 168 } 169 170// if( source != null && target != null || !target.isEmpty() && replacement != null && !replacement.isEmpty() ) { 171// return source.replace( target,replacement ); 172// } 173// else { 174// return source; 175// } 176 } 177 178// /** 179// * この文字列内にあるすべてのoldCharをnewCharに置換した結果生成される文字列を返します。 180// * 181// * String#replace( char , char )を、繰り返します。 182// * 183// * @og.rev 6.7.9.0 (2017/04/28) 新規作成 184// * 185// * @param source 対象の文字列 186// * @param target 以前の文字の集合 187// * @param replacement 置換する文字の集合 188// * @return 置換した文字列。 189// */ 190// public static String translate( final String source , final String target , final String replacement ) { 191// String rtn = source ; 192// 193// if( source != null && target != null && replacement != null && target.length() == replacement.length() ) { 194// for( int i=0; i<target.length(); i++ ) { 195// rtn = rtn.replace( target.charAt(i) , replacement.charAt(i) ); 196// } 197// } 198// 199// return rtn; 200// } 201 202 /** 203 * substr関数のバイト数版 204 * 過去に、hsqldb 用に作成したJava関数です。 205 * 206 * @og.rev 6.8.5.1 (2018/01/15) org.opengion.hsqldb → org.opengion.fukurou.db にパッケージ変更 207 * 208 * @param value 変換する文字列 209 * @param start 変換開始アドレス 210 * @param length 変換バイト数 211 * @return 変換後文字列 212 * @throws UnsupportedEncodingException 文字のエンコーディングがサポートされていません。 213 */ 214 public static String substrb( final String value, final int start, final int length ) throws UnsupportedEncodingException { 215 String rtn = null; 216 final byte[] byteValue = makeByte( value ); 217 if( byteValue != null ) { 218 rtn = new String( byteValue,start-1,length,ENCODE ); 219 } 220 return rtn; 221 } 222 223 /** 224 * length関数のバイト数版 225 * 過去に、hsqldb 用に作成したJava関数です。 226 * 227 * @og.rev 6.8.5.1 (2018/01/15) org.opengion.hsqldb → org.opengion.fukurou.db にパッケージ変更 228 * 229 * @param value バイト数をカウントする文字列 230 * @return バイト数 231 * @throws UnsupportedEncodingException 文字のエンコーディングがサポートされていません。 232 */ 233 public static int lengthb( final String value ) throws UnsupportedEncodingException { 234 return makeByte( value ).length; 235 } 236 237 /** 238 * 指定の文字列をバイトコードに変換します。 239 * 引数の文字列が null の場合は、return は、byte[0] を返します。 240 * 241 * @og.rev 6.8.5.1 (2018/01/15) org.opengion.hsqldb → org.opengion.fukurou.db にパッケージ変更 242 * 243 * @param value 変換するストリング値 244 * @param encode 変換する文字エンコード 245 * @return 変換後文字列 246 */ 247 private static byte[] makeByte( final String value ) throws UnsupportedEncodingException { 248 byte[] rtnByte = new byte[0]; 249 if( value != null ) { 250 rtnByte = value.getBytes( ENCODE ); 251 } 252 return rtnByte; 253 } 254 255 /** 256 * 日時文字列(yyyyMMddHHmmss)の引数1,2に対して、差分の範囲判定を行います。 257 * 258 * 範囲判定を行う引数 sec1、sec2、sec3 引数には、それぞれ(秒)レベルの値を指定します。 259 * 上記の引数の値が、0 の場合は、判定を回避します。 260 * 261 * sec1引数と比べて、小さければ 0 を、大きければ 1 を返します。 262 * sec2引数と比べて、小さければ sec1引数の結果を、大きければ 2 を返します。 263 * sec3引数と比べて、小さければ sec2引数の結果を、大きければ 3 を返します。 264 * 265 * 通常、sec1、sec2、sec3 と、順番に大きな値にしておきます。 266 * 小さいと判定された時点で、判定処理は終了します。 267 * 268 * date2 - date1 <= sec1 ⇒ 0 269 * > sec1 ⇒ 1 270 * > sec2 ⇒ 2 271 * > sec3 ⇒ 3 272 * 273 * date1,date2 のどちらかが、null,ゼロ文字列の場合は、判定しません。(return "0") 274 * 275 * @og.rev 7.0.5.0 (2019/09/16) 新規作成 276 * 277 * @param date1 前比較日時文字列(yyyyMMddHHmmss) 278 * @param date2 後比較日時文字列(yyyyMMddHHmmss) 279 * @param sec1 比較する秒 280 * @param sec2 比較する秒 281 * @param sec3 比較する秒 282 * @return 判定結果 283 */ 284 public static String checkDelay( final String date1 , final String date2 , final double sec1 , final double sec2 , final double sec3 ) { 285 if( StringUtil.isNull( date1,date2 ) ) { return "0"; } // どちらかが、null,ゼロ文字列の場合は、判定しません。 286 287 final Calendar cal1 = HybsDateUtil.getCalendar( date1 ); 288 final Calendar cal2 = HybsDateUtil.getCalendar( date2 ); 289 290 final double diff = ( cal2.getTimeInMillis() - cal1.getTimeInMillis() )/1000.0; // 秒に変換しておきます。 291 292 String rtn = "0"; 293 if( sec1 > 0.0 ) { 294 if( diff <= sec1 ) { return rtn; } 295 else { rtn = "1"; } 296 } 297 298 if( sec2 > 0.0 ) { 299 if( diff <= sec2 ) { return rtn; } 300 else { rtn = "2"; } 301 } 302 303 if( sec3 > 0.0 ) { 304 if( diff <= sec3 ) { return rtn; } 305 else { rtn = "3"; } 306 } 307 308 return rtn; 309 } 310}