Commit 21083efb by Kim Jinsung

アプリログ出力

parent e2ddc8a9
......@@ -7,7 +7,7 @@ android {
minSdkVersion 23
targetSdkVersion 26
versionCode 1
versionName "1.0"
versionName "1.0.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
......
......@@ -13,6 +13,7 @@ import android.widget.Toast;
import jp.odakyu.toiletsignage.R;
import jp.odakyu.toiletsignage.constants.ToiletConstants;
import jp.odakyu.toiletsignage.info.ToiletInfo;
import jp.odakyu.toiletsignage.log.Logger;
import jp.odakyu.toiletsignage.logic.MainLogic;
import jp.odakyu.toiletsignage.application.ToiletApplication;
......@@ -50,12 +51,12 @@ public class MainActivity extends ParentActivity {
int result = MainLogic.getToiletDefaultInfo(getApplicationContext());
if (result == ToiletConstants.VALUE_GET_USB_INFO_VALIDATION_FAIL) {
mMessageTextView.setText(getString(R.string.initDisplayStringError, ToiletInfo.VALUE_DEFAULT_TOILET_VALIDATION_FAIL));
Log.w(TAG, "USBToiletDefaultJson validation fail");
Logger.w(TAG, "USBToiletDefaultJson validation fail");
return;
}
if (result == ToiletConstants.VALUE_GET_USB_INFO_FAIL) {
mMessageTextView.setText(getString(R.string.initDisplayStringError, ToiletInfo.VALUE_DEFAULT_TOILET_NULL));
Log.w(TAG, "ToiletDefaultArray NULL");
Logger.w(TAG, "ToiletDefaultArray NULL");
return;
}
......@@ -65,7 +66,7 @@ public class MainActivity extends ParentActivity {
} catch (Exception e) {
mMessageTextView.setText(getString(R.string.initDisplayStringError, ToiletInfo.VALUE_DEFAULT_TOILET_NULL));
Log.e(TAG, e.getLocalizedMessage(), e);
Logger.e(TAG, e.getLocalizedMessage(), e);
}
}
......@@ -115,7 +116,7 @@ public class MainActivity extends ParentActivity {
@Override
protected void reloadDisplayView(final int errorCount, final boolean isNetworkConnect) {
Log.d(TAG, "reloadDisplayView");
Logger.d(TAG, "reloadDisplayView");
runOnUiThread(new Runnable() {
@Override
public void run() {
......@@ -130,9 +131,9 @@ public class MainActivity extends ParentActivity {
}
} else {
if (isNetworkConnect) {
mMessageTextView.setText(getString(R.string.initDisplayStringError, ToiletInfo.VALUE_NETWORK_DIS_CONNECT));
} else {
mMessageTextView.setText(getString(R.string.initDisplayStringError, ToiletInfo.VALUE_TOILET_SERVER_CONNECT_FAIL));
} else {
mMessageTextView.setText(getString(R.string.initDisplayStringError, ToiletInfo.VALUE_NETWORK_DIS_CONNECT));
}
}
}
......
......@@ -14,6 +14,7 @@ import android.view.Window;
import jp.odakyu.toiletsignage.application.ToiletApplication;
import jp.odakyu.toiletsignage.constants.ToiletConstants;
import jp.odakyu.toiletsignage.info.ToiletInfo;
import jp.odakyu.toiletsignage.log.Logger;
/**
* Created by agentec on 2017/12/11.
......@@ -70,7 +71,7 @@ public class ParentActivity extends AppCompatActivity {
ToiletApplication application = (ToiletApplication) getApplication();
//アプリがバックグラウンドのなった時のみタスクを停止
if (!application.isForeground(this)) {
Log.i(TAG, "Application Background");
Logger.i(TAG, "Application Background");
application.stopTimer();
}
......
......@@ -17,6 +17,7 @@ import jp.odakyu.toiletsignage.constants.ToiletConstants;
import jp.odakyu.toiletsignage.info.ToiletInfo;
import jp.odakyu.toiletsignage.json.ResultToiletJson;
import jp.odakyu.toiletsignage.json.USBToiletDefaultJson;
import jp.odakyu.toiletsignage.log.Logger;
/**
* Created by agentec on 2017/11/30.
......@@ -62,6 +63,7 @@ public class SignageActivity extends ParentActivity {
if (toiletDefaultJson.getPriority() == ToiletInfo.VALUE_PRIORITY_SUB_LEFT) {
leftGateNameJPTextView.setText(toiletDefaultJson.getToiletNameJP());
leftGateNameENTextView.setText(toiletDefaultJson.getToiletNameEN());
} else if (toiletDefaultJson.getPriority() == ToiletInfo.VALUE_PRIORITY_SUB_RIGHT) {
rightGateNameJPTextView.setText(toiletDefaultJson.getToiletNameJP());
rightGateNameENTextView.setText(toiletDefaultJson.getToiletNameEN());
......@@ -129,7 +131,7 @@ public class SignageActivity extends ParentActivity {
*/
@Override
protected void reloadDisplayView(final int errorCount, final boolean isNetworkConnect) {
Log.i(TAG, "reloadDisplayView");
Logger.i(TAG, "reloadDisplayView");
//バックグラウンドスレッドからメーイン
runOnUiThread(new Runnable() {
@Override
......
......@@ -11,7 +11,11 @@ import java.util.List;
import java.util.Timer;
import jp.odakyu.toiletsignage.activity.MainActivity;
import jp.odakyu.toiletsignage.log.Logger;
import jp.odakyu.toiletsignage.task.UpdateToiletInfoTask;
import jp.odakyu.toiletsignage.util.FileUtil;
import static jp.odakyu.toiletsignage.constants.ToiletConstants.APP_LOG_PATH;
/**
* Created by agentec on 2017/12/13.
......@@ -25,21 +29,27 @@ public class ToiletApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
Logger logger = new Logger();
String logPath = getApplicationContext().getCacheDir().getPath() + "/" + APP_LOG_PATH;
logger.setLogPathFormat(logPath);
FileUtil.createParentDirectory(logPath);
Logger.i(TAG, "onCreate");
}
public synchronized void stopTimer() {
Log.i(TAG, "stopTimer");
Logger.i(TAG, "stopTimer");
if (updateToiletInfoTimer != null) {
Log.i(TAG, "stopTimer STOP");
Logger.i(TAG, "stopTimer STOP");
updateToiletInfoTimer.cancel();
updateToiletInfoTimer = null;
}
}
public synchronized void startTimer() {
Log.i(TAG, "startTimer");
Logger.i(TAG, "startTimer");
if (updateToiletInfoTimer == null) {
Log.i(TAG, "startTimer Start");
Logger.i(TAG, "startTimer Start");
updateToiletInfoTimer = new Timer();
// スケジュール開始と同時にすぐ新着更新を開始する
int interval = 10000; //10秒
......
package jp.odakyu.toiletsignage.connection;
import android.util.Base64;
import android.util.Log;
import java.io.BufferedReader;
import java.io.IOException;
......
......@@ -19,4 +19,6 @@ public interface ToiletConstants {
String MEIRIO_FONT_NAME = "meiryo.ttf";
String MEIRIO_BOLD_FONT_NAME = "meiryob.ttf";
String APP_LOG_PATH = "log/appLogcat_%s.log";
}
package jp.odakyu.toiletsignage.log;
public abstract class AbstractLogger { // protectedメソッドにするためinterfaceからabstract classに変更
protected abstract void verbose(String tag, String log);
protected abstract void verbose(String tag, String log, Throwable t);
protected abstract void debug(String tag, String log);
protected abstract void debug(String tag, String log, Throwable t);
protected abstract void info(String tag, String log);
protected abstract void info(String tag, String log, Throwable t);
protected abstract void warn(String tag, String log);
protected abstract void warn(String tag, String log, Throwable t);
protected abstract void error(String tag, String log);
protected abstract void error(String tag, String log, Throwable t);
}
package jp.odakyu.toiletsignage.log;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.util.Date;
import jp.odakyu.toiletsignage.util.DateTimeFormat;
import jp.odakyu.toiletsignage.util.DateTimeUtil;
import jp.odakyu.toiletsignage.util.FileUtil;
public class Logger extends AbstractLogger {
private static AbstractLogger logger = new Logger();
private static PrintStream ps = System.out;
private static String logPathFormat;
private String currentDay;
private int retentionPeriod = 1;
public Logger() {
}
public static AbstractLogger getLogger() {
return logger;
}
public void setLogPathFormat(String logPathFormat) {
this.logPathFormat = logPathFormat;
}
public static void setLogger(AbstractLogger abstractLogger) {
logger = abstractLogger;
}
public void setRetentionPeriod(int retentionPeriod) {
this.retentionPeriod = retentionPeriod;
}
// public static void v(String log) {
// v(env.defaultLogName, log);
// }
public static void v(String tag, String log) {
if (isVerboseEnabled()) {
logger.verbose(tag, log);
}
}
public static void v(String tag, String log, Object... param) {
if (isVerboseEnabled()) {
v(tag, String.format(log, param));
}
}
// public static void v(String log, Throwable t) {
// v(env.defaultLogName, log, t);
// }
public static void v(String tag, String log, Throwable t) {
if (isVerboseEnabled()) {
logger.verbose(tag, log, t);
}
}
// public static void d(String log) {
// d(env.defaultLogName, log);
// }
public static void d(String tag, String log) {
if (isDebugEnabled()) {
logger.debug(tag, log);
}
}
public static void d(String tag, String log, Object... param) {
if (isDebugEnabled()) {
d(tag, String.format(log, param));
}
}
// public static void d(String log, Throwable t) {
// d(env.defaultLogName, log, t);
// }
public static void d(String tag, String log, Throwable t) {
if (isDebugEnabled()) {
logger.debug(tag, log, t);
}
}
// public static void i(String log) {
// i(env.defaultLogName, log);
// }
public static void i(String tag, String log) {
if (isInfoEnabled()) {
logger.info(tag, log);
}
}
public static void i(String tag, String log, Object... param) {
if (isInfoEnabled()) {
i(tag, String.format(log, param));
}
}
// public static void i(String log, Throwable t) {
// i(env.defaultLogName, log, t);
// }
public static void i(String tag, String log, Throwable t) {
if (isInfoEnabled()) {
logger.info(tag, log, t);
}
}
// public static void w(String log) {
// w(env.defaultLogName, log);
// }
public static void w(String tag, String log) {
if (isWarnEnabled()) {
logger.warn(tag, log);
}
}
public static void w(String tag, String log, Object... param) {
if (isWarnEnabled()) {
w(tag, String.format(log, param));
}
}
// public static void w(String log, Throwable t) {
// w(env.defaultLogName, log, t);
// }
public static void w(String tag, String log, Throwable t) {
if (isWarnEnabled()) {
logger.warn(tag, log, t);
}
}
// public static void e(String log) {
// e(env.defaultLogName, log);
// }
public static void e(String tag, String log) {
if (isErrorEnabled()) {
logger.error(tag, log);
}
}
public static void e(String tag, String log, Object... param) {
if (isErrorEnabled()) {
e(tag, String.format(log, param));
}
}
// public static void e(String log, Throwable t) {
// e(env.defaultLogName, log, t);
// }
public static void e(String tag, String log, Throwable t) {
if (isErrorEnabled()) {
logger.error(tag, log, t);
}
}
/**
* #26344 端末ログファイル削除方式改善のため
*/
private boolean isDeletable(File file) {
long toTime = retentionPeriod * 24 * 60 * 60 * 1000; // [retentionPeriod] 日
long fromTime = (retentionPeriod + 7) * 24 * 60 * 60 * 1000; // [retentionPeriod + 7] 日
// fromTime < file.lastModified() < toTime
if (file.lastModified() > System.currentTimeMillis() - fromTime && file.lastModified() < System.currentTimeMillis() - toTime) {
return true;
}
// ファイルのサイズが5Mを超えている場合
if (file.lastModified() < System.currentTimeMillis() - fromTime && file.length() > 5 * 1024 * 1024) {
return true;
}
return false;
}
private void log(String level, String tag, String log) {
Date date = new Date();
String day = DateTimeUtil.toString(date, DateTimeFormat.MMdd_none);
if (logPathFormat != null) {
if (currentDay == null || !currentDay.equals(day)) {
File dir = new File(FileUtil.getParentPath(logPathFormat));
if (dir.exists()) {
File[] files = dir.listFiles();
if (files != null) {
for (File file : files) { // 同一ディレクトリの旧ファイル(retentionPeriod日前)をすべて削除する
// if (file.lastModified() < System.currentTimeMillis() - retentionPeriod * 24 * 60 * 60 * 1000) {
if (isDeletable(file)) {
file.delete();
}
}
}
}
currentDay = day;
try {
ps = new PrintStream(new FileOutputStream(String.format(logPathFormat, day), true));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
String time = DateTimeUtil.toString(date, DateTimeFormat.MMddHHmmssSSS_hyphen);
System.out.println(time + ": [" + level + "] " + tag + "(" + Thread.currentThread().getId() + "): " + log);
}
private void log(String level, String defaultLogName, String log, Throwable e) {
log(level, defaultLogName, log);
e.printStackTrace(ps);
}
@Override
protected void verbose(String tag, String log) {
log("VERBOSE", tag, log);
}
@Override
protected void verbose(String tag, String log, Throwable t) {
log("VERBOSE", tag, log, t);
}
@Override
protected void debug(String tag, String log) {
log("DEBUG", tag, log);
}
@Override
protected void debug(String tag, String log, Throwable t) {
log("DEBUG", tag, log, t);
}
@Override
protected void info(String tag, String log) {
log("INFO", tag, log);
}
@Override
protected void info(String tag, String log, Throwable t) {
log("INFO", tag, log, t);
}
@Override
protected void warn(String tag, String log) {
log("WARN", tag, log);
}
@Override
protected void warn(String tag, String log, Throwable t) {
log("WARN", tag, log, t);
}
@Override
protected void error(String tag, String log) {
log("ERROR", tag, log);
}
@Override
protected void error(String tag, String log, Throwable t) {
log("ERROR", tag, log, t);
}
private static boolean isLoggable(int level) {
return true;
}
public static boolean isVerboseEnabled() {
return true;
}
public static boolean isDebugEnabled() {
return true;
}
public static boolean isInfoEnabled() {
return true;
}
public static boolean isWarnEnabled() {
return true;
}
public static boolean isErrorEnabled() {
return true;
}
}
......@@ -17,6 +17,7 @@ import jp.odakyu.toiletsignage.constants.ToiletConstants;
import jp.odakyu.toiletsignage.file.FileUtil;
import jp.odakyu.toiletsignage.info.ToiletInfo;
import jp.odakyu.toiletsignage.json.USBToiletDefaultJson;
import jp.odakyu.toiletsignage.log.Logger;
/**
* Created by agentec on 2017/12/08.
......@@ -46,14 +47,14 @@ public class MainLogic {
for(String directoryName:rootStorageDirectory) {
String jsonFilePath = directoryName + TOILET_INFO_JSON;
Log.d(TAG, jsonFilePath);
Logger.d(TAG, jsonFilePath);
File uspJsonFile = new File(jsonFilePath);
if (uspJsonFile.exists() && uspJsonFile.isFile()) {
FileUtil.fileCopy(jsonFilePath, copyFilePath);
break;
} else {
Log.w(TAG, "usb json file not exists = " + jsonFilePath);
Logger.w(TAG, "usb json file not exists = " + jsonFilePath);
}
}
......@@ -80,7 +81,10 @@ public class MainLogic {
} else {
return ToiletConstants.VALUE_GET_USB_INFO_FAIL;
}
} else {
return ToiletConstants.VALUE_GET_USB_INFO_FAIL;
}
return ToiletConstants.VALUE_GET_USB_INFO_SUCCESS;
}
......@@ -95,7 +99,7 @@ public class MainLogic {
if (file != null) {
int index = file.getAbsolutePath().lastIndexOf("/Android/data");
if (index < 0) {
Log.w("AmazeFileUtils", "Unexpected external file dir: " + file.getAbsolutePath());
Logger.w("AmazeFileUtils", "Unexpected external file dir: " + file.getAbsolutePath());
} else {
String path = file.getAbsolutePath().substring(0, index);
try {
......@@ -103,9 +107,8 @@ public class MainLogic {
pathList.add(canonicalPath);
} catch (IOException e) {
// Keep non-canonical path.
Log.e(TAG, e.getLocalizedMessage(), e);
Logger.e(TAG, e.getLocalizedMessage(), e);
}
}
}
}
......
......@@ -16,6 +16,7 @@ import jp.odakyu.toiletsignage.constants.ToiletConstants;
import jp.odakyu.toiletsignage.info.ToiletInfo;
import jp.odakyu.toiletsignage.json.ResultToiletJson;
import jp.odakyu.toiletsignage.json.USBToiletDefaultJson;
import jp.odakyu.toiletsignage.log.Logger;
/**
* Created by agentec on 2017/12/11.
......@@ -37,7 +38,7 @@ public class UpdateToiletInfoTask extends TimerTask {
*/
@Override
public void run() {
Log.i(TAG, "Thread Start");
Logger.i(TAG, "Thread Start");
boolean isNetworkConnect = true;
//インターネット接続チェック
if (isNetworkAvailable(applicationContext)) {
......@@ -47,11 +48,11 @@ public class UpdateToiletInfoTask extends TimerTask {
try {
String jsonString = ToiletServerConnection.connectionToiletServer(toiletDefaultJson.getToiletId());
if (jsonString == null) {
Log.w(TAG,"json object null jsonString");
Logger.w(TAG,"json object null jsonString");
isError = true;
break;
}
Log.d(TAG,"jsonString = " + jsonString);
Logger.d(TAG,"jsonString = " + jsonString);
JSONObject jsonObject = new JSONObject(jsonString);
ArrayList<ResultToiletJson> resultToiletJsonArray = new ArrayList<>();
......@@ -63,7 +64,7 @@ public class UpdateToiletInfoTask extends TimerTask {
ToiletInfo.getInstance().setResultToiletJsonMap(toiletDefaultJson.getToiletId(), resultToiletJsonArray);
} catch (Exception e) {
Log.e(TAG, e.getLocalizedMessage(), e);
Logger.e(TAG, e.getLocalizedMessage(), e);
isError = true;
break;
}
......@@ -84,7 +85,7 @@ public class UpdateToiletInfoTask extends TimerTask {
intent.putExtra(ToiletConstants.KEY_NETWORK_CONNECT, isNetworkConnect);
applicationContext.sendBroadcast(intent);
Log.d(TAG, "Thread End");
Logger.d(TAG, "Thread End");
}
/**
......
package jp.odakyu.toiletsignage.util;
/**
* 日付や時刻を表すフォーマットの集合です。
* @author Taejin Hong
* @version
*/
public class DateTimeFormat {
/**
* 4桁の年を示します。"yyyy"
* @since 1.0.0
*/
public static final String yyyy = "yyyy";
/**
* 2桁の月を示します。"MM"
* @since 1.0.0
*/
public static final String MM = "MM";
/**
* 2桁の日を示します。"dd"
* @since 1.0.0
*/
public static final String dd = "dd";
/**
* 2桁の時を示します。"HH"
* @since 1.0.0
*/
public static final String HH = "HH";
/**
* 2桁の分を示します。"mm"
* @since 1.0.0
*/
public static final String mm = "mm";
/**
* 2桁の秒を示します。"ss"
* @since 1.0.0
*/
public static final String ss = "ss";
/**
* 3桁の秒を示します。"SSS"
* @since 1.0.0
*/
public static final String SSS = "SSS";
/**
* 日付を示します。"yyyymm"
* @since 1.0.0
*/
public static final String yyyyMM_none = "yyyymm";
/**
* 日付を示します。"yyyy/mm"
* @since 1.0.0
*/
public static final String yyyyMM_slash = "yyyy/mm";
/**
* 日付を示します。"yyyy-mm"
* @since 1.0.0
*/
public static final String yyyyMM_hyphen = "yyyy-mm";
/**
* 日付を示します。"yyyyMMdd"
* @since 1.0.0
*/
public static final String yyyyMMdd_none = "yyyyMMdd";
/**
* 日付を示します。"yyyy/MM/dd"
* @since 1.0.0
*/
public static final String yyyyMMdd_slash = "yyyy/MM/dd";
/**
* 日付を示します。"yyyy-MM-dd"
* @since 1.0.0
*/
public static final String yyyyMMdd_hyphen = "yyyy-MM-dd";
/**
* 日付を示します。"yyyy.MM.dd"
* @since 1.0.0
*/
public static final String yyyyMMdd_dot = "yyyy.MM.dd";
/**
* 日付を示します。"MMdd"
* @since 1.0.0
*/
public static final String MMdd_none = "MMdd";
/**
* 日付を示します。"MM/dd"
* @since 1.0.0
*/
public static final String MMdd_slash = "MM/dd";
/**
* 日付を示します。"MM-dd"
* @since 1.0.0
*/
public static final String MMdd_hyphen = "MM-dd";
/**
* 日付を示します。"MM-dd"
* @since 1.0.0
*/
public static final String MMddHHmm_hyphen = "MM-dd HH:mm";
/**
* 日付を示します。"yyyyMMddHH"
* @since 1.0.0
*/
public static final String yyyyMMddHH_none = "yyyyMMddHH";
/**
* 日付を示します。"yyyy/MM/dd HH"
* @since 1.0.0
*/
public static final String yyyyMMddHH_slash = "yyyy/MM/dd HH";
/**
* 日付を示します。"yyyy-MM-dd HH"
* @since 1.0.0
*/
public static final String yyyyMMddHH_hyphen = "yyyy-MM-dd HH";
/**
* 日付を示します。"yyyyMMddHH00"
* @since 1.0.0
*/
public static final String yyyyMMddHH00_none = "yyyyMMddHH00";
/**
* 日付を示します。"yyyy/MM/dd HH:00"
* @since 1.0.0
*/
public static final String yyyyMMddHH00_slash = "yyyy/MM/dd HH:00";
/**
* 日付を示します。"yyyy-MM-dd HH:00"
* @since 1.0.0
*/
public static final String yyyyMMddHH00_hyphen = "yyyy-MM-dd HH:00";
/**
* 日付を示します。"yyyyMMddHHmm"
* @since 1.0.0
*/
public static final String yyyyMMddHHmm_none = "yyyyMMddHHmm";
/**
* 日付を示します。"yyyy/MM/dd HH:mm"
* @since 1.0.0
*/
public static final String yyyyMMddHHmm_slash = "yyyy/MM/dd HH:mm";
/**
* 日付を示します。"yyyy-MM-dd HH:mm"
* @since 1.0.0
*/
public static final String yyyyMMddHHmm_hyphen = "yyyy-MM-dd HH:mm";
/**
* 日付を示します。"yyyyMMddHHmm00"
* @since 1.0.0
*/
public static final String yyyyMMddHHmm00_none = "yyyyMMddHHmm00";
/**
* 日付を示します。"yyyy/MM/dd HH:mm:00"
* @since 1.0.0
*/
public static final String yyyyMMddHHmm00_slash = "yyyy/MM/dd HH:mm:00";
/**
* 日付を示します。"yyyy-MM-dd HH:mm:00"
* @since 1.0.0
*/
public static final String yyyyMMddHHmm00_hyphen = "yyyy-MM-dd HH:mm:00";
/**
* 日付を示します。"yyyyMMddHHmmss"
* @since 1.0.0
*/
public static final String yyyyMMddHHmmss_none = "yyyyMMddHHmmss";
/**
* 日付を示します。"yyyy/MM/dd HH:mm:ss"
* @since 1.0.0
*/
public static final String yyyyMMddHHmmss_slash = "yyyy/MM/dd HH:mm:ss";
/**
* 日付を示します。"yyyy-MM-dd HH:mm:ss"
* @since 1.0.0
*/
public static final String yyyyMMddHHmmss_hyphen = "yyyy-MM-dd HH:mm:ss";
public static final String MMddHHmmssSSS_hyphen = "MM-dd HH:mm:ss.SSS";
/**
* 日付を示します。"yyyyMMddHHmmss000"
* @since 1.0.0
*/
public static final String yyyyMMddHHmmss000_none = "yyyyMMddHHmmss000";
/**
* 日付を示します。"yyyy/MM/dd HH:mm:ss.000"
* @since 1.0.0
*/
public static final String yyyyMMddHHmmss000_slash = "yyyy/MM/dd HH:mm:ss.000";
/**
* 日付を示します。"yyyy-MM-dd HH:mm:ss.000"
* @since 1.0.0
*/
public static final String yyyyMMddHHmmss000_hyphen = "yyyy-MM-dd HH:mm:ss.000";
/**
* 日付を示します。"yyyyMMddHHmmssSSS"
* @since 1.0.0
*/
public static final String yyyyMMddHHmmssSSS_none = "yyyyMMddHHmmssSSS";
/**
* 日付を示します。"yyyy/MM/dd HH:mm:ss.SSS"
* @since 1.0.0
*/
public static final String yyyyMMddHHmmssSSS_slash = "yyyy/MM/dd HH:mm:ss.SSS";
/**
* 日付を示します。"yyyy-MM-dd HH:mm:ss.SSS"
* @since 1.0.0
*/
public static final String yyyyMMddHHmmssSSS_hyphen = "yyyy-MM-dd HH:mm:ss.SSS";
/**
* 日付を示します。"yyyy-MM-dd HH:mm:ss"
* @since 1.0.0
*/
public static final String yyyyMMddHHmmss_TZ = "yyyy-MM-dd'T'HH:mm:ss'Z'";
/**
* 日付を示します。"yyyy-MM-ddTHH:mm:ss.SSS"
* @since 1.0.0
*/
public static final String yyyyMMddHHmmssSSS_TZ = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
/**
* 日付を示します。 "EEE, dd MMM yyyy HH:mm:ss"
* @since 1.0.0
*/
public static final String ifModifiedSinceType = "EEE, dd MMM yyyy HH:mm:ss";
/**
* 時間を示します。"HHmm"
* @since 1.0.0
*/
public static final String HHmm_none = "HHmm";
/**
* 時間を示します。"HH:mm"
* @since 1.0.0
*/
public static final String HHmm_colon = "HH:mm";
/**
* 時間を示します。"HHmmss"
* @since 1.0.0
*/
public static final String HHmmss_none = "HHmmss";
/**
* 時間を示します。"HH:mm:ss"
* @since 1.0.0
*/
public static final String HHmmss_colon = "HH:mm:ss";
/**
* 時間を示します。"HHmmssSSS"
* @since 1.0.0
*/
public static final String HHmmssSSS_none = "HHmmssSSS";
/**
* 時間を示します。"HH:mm:ss.SSS"
* @since 1.0.0
*/
public static final String HHmmssSSS_colon = "HH:mm:ss.SSS";
}
package jp.odakyu.toiletsignage.util;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
import jp.odakyu.toiletsignage.log.Logger;
/**
* 日付・時間関連の機能を提供します。
* @author Taejin Hong
* @version 1.0.0
*
*/
public class DateTimeUtil {
public enum DateUnit {
Millisecond,
Second,
Minute,
Hour,
Day,
Month,
Year
}
/**
* 現在日時を返却します
* @return 現在日時の{@link Timestamp}
* @since 1.0.0
*/
public static Timestamp getCurrentTimestamp() {
return new Timestamp(System.currentTimeMillis());
}
/**
* 現在時刻を返却します。
* @return 現在日時の{@link Date}
* @since 1.0.0
*/
public static Date getCurrentDate() {
return new Date(getCurrentTimestamp().getTime());
}
/**
* 現在時刻(UTC)を返却します。
* @return 現在日時の{@link String}
*/
public static Date getCurrentUTCDate() {
SimpleDateFormat df = new SimpleDateFormat(DateTimeFormat.yyyyMMddHHmmssSSS_TZ);
df.setTimeZone(TimeZone.getTimeZone("UTC"));
String gmtTime = df.format(getCurrentDate());
Date utcDate = null;
try {
utcDate = df.parse(gmtTime);
} catch (ParseException e) {
}
return utcDate;
}
/**
* UTC時刻を返却します。
* @param date {@link Date}
* @return UTC日時{@link String}
*/
public static String getUTCDate(Date date) {
SimpleDateFormat df = new SimpleDateFormat(DateTimeFormat.yyyyMMddHHmmssSSS_TZ);
df.setTimeZone(TimeZone.getTimeZone("UTC"));
String gmtTime = df.format(date);
return gmtTime;
}
/**
* 現在時刻を返却します。
* @return 現在日時の{@link java.sql.Date}
* @since 1.0.0
*/
public static java.sql.Date getCurrentSqlDate() {
return new java.sql.Date(getCurrentTimestamp().getTime());
}
/**
* 文字列を {@link Timestamp} 型に変換します。変換時例外が発生した場合はnullを返却します。<br>
* Example : {@code DateTimeUtil.gettimestamp("2011-12-02 17:08:16", DateTimeFormat.yyyyMMddHHmmss_dash);}
* @param time 時間を示す文字列
* @param format タイムスタンプのフォーマット(ハイフン又はスラッシュ区切りであること)
* @return 変換した {@link Timestamp} のインスタンス。
* @since 1.0.0
*/
public static Timestamp toTimestamp(String time, String format) {
Timestamp timestamp = null;
if (!StringUtil.isNullOrWhiteSpace(time) && !StringUtil.isNullOrWhiteSpace(format)) {
time = time.replaceAll(StringUtil.Slash, StringUtil.Hyphen);
try {
timestamp = new Timestamp(new SimpleDateFormat(format).parse(time).getTime());
} catch (Exception e) {}
}
return timestamp;
}
/**
* 指定した date を指定した format のDateに変換します。
* @param date 変換する {@link Date} です。
* @param format タイムスタンプのフォーマット
* @return 変換したDate
*/
public static Date formatDate(Date date, String format) {
Date newDate = null;
if (date != null && !StringUtil.isNullOrWhiteSpace(format)) {
SimpleDateFormat sdf = new SimpleDateFormat(format);
String s = sdf.format(date);
try {
newDate = sdf.parse(s);
} catch (ParseException e) {
}
}
return newDate;
}
/**
* 文字列を {@link Date} 型に変換します。変換時例外が発生した場合はnullを返却します。<br>
* Example : {@code DateTimeUtil.gettimestamp("2011-12-02 17:08:16", DateTimeFormat.yyyyMMddHHmmss_dash);}
* @param time 時間を示す文字列
* @param format タイムスタンプのフォーマット(ハイフン又はスラッシュ区切りであること)
* @return 変換した{@link Date}のインスタンス。
* @since 1.0.0
*/
public static Date toDate(String time, String format) {
Date dt = null;
if (!StringUtil.isNullOrWhiteSpace(time) && !StringUtil.isNullOrWhiteSpace(time)) {
try {
dt = new Date(new SimpleDateFormat(format).parse(time).getTime());
} catch (Exception e) {
Logger.e("DateTimeUtil", "[toDate]:" + time + ", format=" + format, e);
}
}
return dt;
}
/**
* 文字列を {@link Date} 型に変換します。変換時例外が発生した場合はnullを返却します。<br>
*
* @param time
* @param timeZone タイムゾーン(引数のtimeのタイムゾーン)
* @param format
* @return
*/
public static Date toDate(String time, String timeZone, String format) {
Date dt = null;
if (!StringUtil.isNullOrWhiteSpace(time) && !StringUtil.isNullOrWhiteSpace(time)) {
time = time.replaceAll(StringUtil.Slash, StringUtil.Hyphen);
try {
SimpleDateFormat sdf = new SimpleDateFormat(format);
sdf.setTimeZone(TimeZone.getTimeZone(timeZone));
dt = new Date(sdf.parse(time).getTime());
} catch (Exception e) {}
}
return dt;
}
/**
* 文字列を {@link java.sql.Date} 型に変換します。変換時例外が発生した場合はnullを返却します。<br>
* Example : {@code DateTimeUtil.gettimestamp("2011-12-02 17:08:16", DateTimeFormat.yyyyMMddHHmmss_dash);}
* @param time 時間を示す文字列
* @param format タイムスタンプのフォーマット(ハイフン又はスラッシュ区切りであること)
* @return 変換した{@link java.sql.Date}のインスタンス。
* @since 1.0.0
*/
public static java.sql.Date toSqlDate(String time, String format) {
java.sql.Date dt = null;
if (!StringUtil.isNullOrWhiteSpace(time) && !StringUtil.isNullOrWhiteSpace(time)) {
time = time.replaceAll(StringUtil.Slash, StringUtil.Hyphen);
try {
dt = new java.sql.Date(new SimpleDateFormat(format).parse(time).getTime());
} catch (Exception e) {}
}
return dt;
}
/**
* 指定した date を指定した format の文字列に変換します。
* @param date 変換する {@link Date} です。
* @param format 変換する文字列のフォーマットです。 {@link DateTimeFormat} に色々なフォーマットを予め定義しています。
* @return 変換した文字列を返します。
* @since 1.0.0
*/
public static String toString(Date date, String format) {
String s = null;
if (date != null && !StringUtil.isNullOrWhiteSpace(format)) {
s = new SimpleDateFormat(format).format(date);
}
return s;
}
/**
* 指定した date を指定した format の文字列に変換します。
* @param date 変換する {@link Date} です。
* @param format 変換する文字列のフォーマットです。 {@link DateTimeFormat} に色々なフォーマットを予め定義しています。
* @param timeZone 変換結果のタイムゾーンです。
* @return 変換した文字列を返します。
* @since 1.0.0
*/
public static String toStringInTimeZone(Date date, String format, String timeZone) {
String s = null;
if (date != null && !StringUtil.isNullOrWhiteSpace(format)) {
SimpleDateFormat df = new SimpleDateFormat(format);
df.setTimeZone(TimeZone.getTimeZone(timeZone));
s = df.format(date);
}
return s;
}
/**
* 指定した date を指定した format の文字列に変換します。
* @param date 変換する {@link java.sql.Date} です。
* @param format 変換する文字列のフォーマットです。 {@link DateTimeFormat} に色々なフォーマットを予め定義しています。
* @return 変換した文字列を返します。
* @since 1.0.0
*/
public static String toString(java.sql.Date date, String format) {
String s = null;
if (date != null && !StringUtil.isNullOrWhiteSpace(format)) {
s = new SimpleDateFormat(format).format(date);
}
return s;
}
/**
* 指定した date を指定した format の文字列に変換します。
* @param date 変換する {@link java.sql.Date} です。
* @param format 変換する文字列のフォーマットです。 {@link DateTimeFormat} に色々なフォーマットを予め定義しています。
* @param timeZone 変換結果のタイムゾーンです。
* @return 変換した文字列を返します。
* @since 1.0.0
*/
public static String toStringInTimeZone(java.sql.Date date, String format, String timeZone) {
String s = null;
if (date != null && !StringUtil.isNullOrWhiteSpace(format)) {
SimpleDateFormat df = new SimpleDateFormat(format);
df.setTimeZone(TimeZone.getTimeZone(timeZone));
s = df.format(date);
}
return s;
}
/**
* 二つの時間の差を計算します。
* @param beforeDate 比較する日付です。
* @param afterDate 比較する日付です。
* @return 時間の差をミリ秒で返します。
* @since 1.0.0
*/
public static int TimeLagToInt(Date beforeDate, Date afterDate) {
long duration;
long before = 0;
long after = 0;
if (beforeDate != null) {
Calendar beforeCal = Calendar.getInstance();
beforeCal.setTime(beforeDate);
before = beforeCal.getTimeInMillis();
}
if (afterDate != null) {
Calendar afterCal = Calendar.getInstance();
afterCal.setTime(afterDate);
after = afterCal.getTimeInMillis();
}
duration=(after - before);
return (int)duration;
}
/**
* 二つの時間の差を計算します。
* @param beforeDate 比較する日付です。
* @param afterDate 比較する日付です。
* @return 時間の差をミリ秒で返します。
* @since 1.0.0
*/
public static int SqlTimeLagToInt(java.sql.Date beforeDate, java.sql.Date afterDate) {
long duration;
long before = 0;
long after = 0;
if (beforeDate != null) {
Calendar beforeCal = Calendar.getInstance();
beforeCal.setTime(beforeDate);
before = beforeCal.getTimeInMillis();
}
if (afterDate != null) {
Calendar afterCal = Calendar.getInstance();
afterCal.setTime(afterDate);
after = afterCal.getTimeInMillis();
}
duration=(after - before);
return (int)duration;
}
/**
* 二つの時間の差を計算します。
* @param beforeDate 比較する日付です。
* @param afterDate 比較する日付です。
* @return 時間の差をミリ秒で返します。
* @since 1.0.0
*/
public static long TimeLagToLong(Date beforeDate,Date afterDate) {
long duration;
long before = 0;
long after = 0;
if (beforeDate != null) {
Calendar beforeCal = Calendar.getInstance();
beforeCal.setTime(beforeDate);
before = beforeCal.getTimeInMillis();
}
if (afterDate != null) {
Calendar afterCal = Calendar.getInstance();
afterCal.setTime(afterDate);
after = afterCal.getTimeInMillis();
}
duration=(before - after);
return (int)duration;
}
/**
* 二つの時間の差を計算します。
* @param beforeDate 比較する日付です。
* @param afterDate 比較する日付です。
* @return 時間の差をミリ秒で返します。
* @since 1.0.0
*/
public static long SqlTimeLagToLong(java.sql.Date beforeDate, java.sql.Date afterDate) {
long duration;
long before = 0;
long after = 0;
if (beforeDate != null) {
Calendar beforeCal = Calendar.getInstance();
beforeCal.setTime(beforeDate);
before = beforeCal.getTimeInMillis();
}
if (afterDate != null) {
Calendar afterCal = Calendar.getInstance();
afterCal.setTime(afterDate);
after = afterCal.getTimeInMillis();
}
duration=(before - after);
return (int)duration;
}
/**
* {@link Date} を {@link java.sql.Date} に変換します。
* @param dt 変換する {@link Date} のインスタンスです。
* @return 変換した {@link java.sql.Date} のインスタンスを返します。
* @since 1.0.0
*/
public static java.sql.Date dateToSqlDate(Date dt) {
if (dt != null) {
return new java.sql.Date(dt.getTime());
} else {
return null;
}
}
/**
* {@link java.sql.Date} を {@link Date} に変換します。
* @param sqlDt 変換する {@link java.sql.Date} のインスタンスです。
* @return 変換した {@link Date} のインスタンスを返します。
* @since 1.0.0
*/
public static Date sqlDateToDate(java.sql.Date sqlDt) {
if (sqlDt != null) {
return new Date(sqlDt.getTime());
} else {
return null;
}
}
/**
* {@link Date} を {@link Timestamp} に変換します。
* @param dt 変換する {@link Date} のインスタンスです。
* @return 変換した {@link Timestamp} のインスタンスを返します。
* @since 1.0.0
*/
public static Timestamp dateToTimestamp(Date dt) {
if (dt != null) {
return new Timestamp(dt.getTime());
} else {
return null;
}
}
/**
* {@link java.sql.Date} を {@link Timestamp} に変換します。
* @param sqlDt 変換する {@link java.sql.Date} のインスタンスです。
* @return 変換した {@link Timestamp} のインスタンスを返します。
* @since 1.0.0
*/
public static Timestamp sqlDateToTimestamp(java.sql.Date sqlDt) {
if (sqlDt != null) {
return new Timestamp(sqlDt.getTime());
} else {
return null;
}
}
public static Date add(Date dt, DateUnit unit, int value) {
if (dt != null && unit != null) {
Calendar cal = Calendar.getInstance();
cal.setTime(dt);
int field = -1;
switch (unit) {
case Millisecond:
field = Calendar.MILLISECOND;
break;
case Second:
field = Calendar.SECOND;
break;
case Minute:
field = Calendar.MINUTE;
break;
case Hour:
field = Calendar.HOUR;
break;
case Day:
field = Calendar.DATE;
break;
case Month:
field = Calendar.MONTH;
break;
case Year:
field = Calendar.YEAR;
break;
}
cal.add(field, value);
return cal.getTime();
} else {
return null;
}
}
public static java.sql.Date add(java.sql.Date dt, DateUnit unit, int value) {
if (dt != null && unit != null) {
Calendar cal = Calendar.getInstance();
cal.setTime(dt);
int field = -1;
switch (unit) {
case Millisecond:
field = Calendar.MILLISECOND;
break;
case Second:
field = Calendar.SECOND;
break;
case Minute:
field = Calendar.MINUTE;
break;
case Hour:
field = Calendar.HOUR;
break;
case Day:
field = Calendar.DATE;
break;
case Month:
field = Calendar.MONTH;
break;
case Year:
field = Calendar.YEAR;
break;
}
cal.add(field, value);
return dateToSqlDate(cal.getTime());
} else {
return null;
}
}
/**
* 時間の形式(hh:mm:ss)に変換する
*
* @param duration
* @return
*/
public static String toTimeFormat(int duration) {
int hours = duration / (1000*60*60);
int minutes = duration % (1000*60*60) / (1000*60);
int seconds = (duration % (1000*60*60)) % (1000*60) / 1000;
return (hours>0? hours+":": "") + minutes + ":" + (seconds<10?"0":"") + seconds;
}
/**
* 端末のTimeZoneを取得
* @return LocalのTimezone
*/
public static String getLocalTimeZone() {
Calendar c = Calendar.getInstance();
TimeZone tz = c.getTimeZone();
return tz.getID();
}
/**
* 時間の形式(EEE, dd MMM yyyy HH:mm:ss GMT)に変換する
*
* @param date
* @return
*/
public static String lastModifiedConnectFormatGmt(Date date) {
SimpleDateFormat df = new SimpleDateFormat(DateTimeFormat.ifModifiedSinceType, Locale.US);
df.setTimeZone(TimeZone.getTimeZone("GMT"));
return df.format(date)+ " GMT";
}
}
package jp.odakyu.toiletsignage.util;
//import net.lingala.zip4j.exception.ZipException;
//import net.lingala.zip4j.io.ZipOutputStream;
//import net.lingala.zip4j.model.ZipParameters;
//import net.lingala.zip4j.util.Zip4jConstants;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.math.BigDecimal;
import java.nio.channels.FileChannel;
//import java.security.NoSuchAlgorithmException;
//import java.util.ArrayList;
import jp.odakyu.toiletsignage.log.Logger;
/**
* ファイルIOに関する機能を提供します。一部のメソッドはSinaburoUtilから移植しています。
* @author Taejin Hong
* @version 1.1.0
*/
public class FileUtil {
public static final char Slash = '/';
public static final char BackSlash = '\\';
private static final String RegexRotationFileNameWithoutExt = ".*-\\d{2}$";
/**
* byteのサイズをわかりやすく表現します。(*B/*K/*M/*G)
* @param size byteを指定します。
* @return 分かりやすくした文字列を返します。
* @since 1.0.0
*/
public static String formatByte(long size) {
if (size / 1024 < 1) {
return size + "B";
} else if (size / (1024*1024) < 1) {
return size / 1024 + "K";
} else if (size / (1024*1024*1024) < 1) {
return size / (1024*1024) + "M";
} else {
return size / (1024*1024*1024) + "G";
}
}
/**
* ファイルサイズに単位をつける
* (小数点第一位まで)
*
* @param fileSize
* @return
*/
public static String formatByte2(long fileSize) {
String ret;
if (fileSize > 1024 * 1024 * 1024) {
ret = new BigDecimal((double)fileSize / (1024 * 1024 * 1024)).setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue() + "GB";
}
else if (fileSize > 1024 * 1024) {
ret = new BigDecimal((double)fileSize / (1024 * 1024)).setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue() + "MB";
}
else if (fileSize > 1024) {
ret = new BigDecimal((double)fileSize / 1024).setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue() + "KB";
}
else {
ret = fileSize + "B";
}
return ret;
}
/**
* ファイル名から拡張子を取り出します。
* @param filename ファイル名です。
* @return ファイルの拡張子を返します。拡張子がない場合空文字を返します。
* @since 1.0.0
*/
public static String getExtension(String filename) {
if (StringUtil.isNullOrWhiteSpace(filename)) {
return StringUtil.Empty;
}
int lastIndex = filename.lastIndexOf(".");
if (lastIndex == -1) {
return StringUtil.Empty;
} else {
return filename.substring(lastIndex + 1);
}
}
/**
* 拡張子を除いたファイル名を取り出します。
* @param filename ファイル名です。
* @return 拡張子を除いたファイル名を返します。
* @since 1.0.0
*/
public static String getFilenameWithoutExt(String filename) {
if (StringUtil.isNullOrWhiteSpace(filename)) {
return StringUtil.Empty;
}
filename = getFileName(filename);
int lastIndex = filename.lastIndexOf(".");
if (lastIndex == -1) {
return filename;
} else {
return filename.substring(0, lastIndex);
}
}
/**
* 指定したパスから親のパスを取り出します。
* @param path パスを指定します。パスの最後は/(又は\)を含めます。
* @return 親のパスを返します。親のパスがない場合、空文字を返します。
* @since 1.0.0
*/
public static String getParentPath(String path) {
if (StringUtil.isNullOrWhiteSpace(path)) {
return StringUtil.Empty;
}
File f = new File(path);
return f.getParent() + File.separator;
}
/**
* 指定したパスからファイル名を取り出します。
* @param path パスを指定します。
* @return ファイル名を返します。パスにファイル名が含まれてない場合、空文字を返します。
* @since 1.0.0
*/
public static String getFileName(String path) {
if (StringUtil.isNullOrWhiteSpace(path)) {
return StringUtil.Empty;
}
int index = path.lastIndexOf(Slash);
if (index == -1) {
index = path.lastIndexOf(BackSlash);
}
if (index > 0) {
return path.substring(index + 1);
} else {
return path;
}
}
/**
* パスの終端にシステムに依存するパス区切りをつけます。
* @param path パスを指定します。
* @return 区切りをつけたパスを返します。パスに既に区切りがついている場合は、そのまま返します。
* @since 1.0.0
*/
public static String addPathSeparator(String path) {
return addPathSeparator(path, File.separator);
}
/**
* パスの終端に指定したパス区切りをつけます。
* @param path パスを指定します。
* @param separator パスの区切りです。
* @return 区切りをつけたパスを返します。パスに既に区切りがついている場合は、そのまま返します。
* @since 1.0.0
*/
private static String addPathSeparator(String path, String separator) {
if (path != null && separator != null) {
path = path.trim();
if (path.length() > 0 && path.lastIndexOf(separator) != path.length() - 1) {
path += separator;
}
}
return path;
}
/**
* 指定したパスのファイルを作成します。パスのディレクトリが存在しない場合、ディレクトリも作成します。
* @param filePath ファイルのフルパスを指定します。
* @return ファイルの新規作成に成功又は、ファイルが既に存在する場合はtrueを返します。
* @throws IOException I/O例外により、ファイルの作成ができませんでした。
* @since 1.0.0
*/
public static boolean createNewFile(String filePath) throws IOException {
boolean result = createParentDirectory(filePath);
if (result) {
File file = new File(filePath);
file.createNewFile();
}
return result;
}
/**
* 指定したパスのディレクトリを作成します。親ディレクトリが存在しない場合、親ディレクトリも作成します。
* @param dirPath 作成するディレクトのパスを指定します。
* @return ディレクトリの新規作成に成功又は、ディレクトリが既に存在する場合はtrueを返します。
* @throws IOException I/O例外により、ディレクトリの作成ができませんでした。
* @since 1.0.0
*/
public static boolean createNewDirectory(String dirPath) {
boolean result = false;
if (!StringUtil.isNullOrWhiteSpace(dirPath)) {
File dir = new File(dirPath);
result = dir.exists();
if (!result) {
result = dir.mkdirs();
}
}
return result;
}
/**
* 指定したファイルパスの親ディレクトリを作成します。
* @param filePath ファイルのパスです。
* @return ディレクトリを作成したか、既に存在する場合、trueを返します。
* @throws IOException I/O例外により、ディレクトリの作成ができませんでした。
* @since 1.0.0
*/
public static boolean createParentDirectory(String filePath) {
boolean result = false;
if (!StringUtil.isNullOrWhiteSpace(filePath)) {
result = createNewDirectory(getParentPath(filePath));
}
return result;
}
/**
* 指定したパスのファイル又はフォルダーを削除します。<br>
* パスがフォルダーを示している場合、フォルダーの下位ファイル及びフォルダも全て削除します。
* @param f 削除するパスを指定します。
* @return 削除が成功したらtrueを返します。指定したパスが存在しない場合もtrueを返します。一部でも削除できなかった場合、処理をすぐ中断し、falseを返します。
* @since 1.0.0
*/
public static boolean delete(File f) {
boolean result = false;
if (f != null) {
if (f.exists()) {
if (f.isDirectory()) {
File[] childs = f.listFiles();
if (childs != null) {
for (File child : childs) {
if (!(result = delete(child))) {
break;
}
}
if (result || childs.length == 0) {
result = f.delete();
}
}
else {
result = f.delete();
}
} else {
result = f.delete();
}
} else {
result = true;
}
}
return result;
}
/**
* 指定したパスのファイル又はフォルダーを削除します。<br>
* パスがフォルダーを示している場合、フォルダーの下位ファイル及びフォルダも全て削除します。
* @param path  削除するパスを指定します。
* @return 削除が成功したらtrueを返します。指定したパスが存在しない場合もtrueを返します。
* @since 1.0.0
*/
public static boolean delete(String path) {
boolean result = false;
if (!StringUtil.isNullOrWhiteSpace(path)) {
result = delete(new File(path));
}
return result;
}
/**
* 指定したパスのファイル又はフォルダーの直下のファイルを削除します。<br>
* パスがフォルダーを示している場合、フォルダーの下位ファイルのみ削除します。フォルダ次第は削除しません。
* @param f 削除するパスを指定します。
* @return 削除が成功したらtrueを返します。指定したパスが存在しない場合もtrueを返します。一部でも削除できなかった場合、処理をすぐ中断し、falseを返します。
* @since 1.1.0
*/
public static boolean deleteFileOnly(File f) {
boolean result = false;
if (f != null) {
if (f.exists()) {
if (f.isDirectory()) {
File[] childs = f.listFiles(new FileFilter() {
@Override
public boolean accept(File f) {
return f.isFile();
}
});
if (childs != null) {
for (File child : childs) {
if (!(result = child.delete())) {
break;
}
}
}
} else {
result = f.delete();
}
} else {
result = true;
}
}
return result;
}
/**
* 指定したパスのファイル又はフォルダーの直下のファイルを削除します。<br>
* パスがフォルダーを示している場合、フォルダーの下位ファイルのみ削除します。フォルダ次第は削除しません。
* @param path 削除するパスを指定します。
* @return 削除が成功したらtrueを返します。指定したパスが存在しない場合もtrueを返します。一部でも削除できなかった場合、処理をすぐ中断し、falseを返します。
* @since 1.1.0
*/
public static boolean deleteFileOnly(String path) {
boolean result = false;
if (!StringUtil.isNullOrWhiteSpace(path)) {
result = deleteFileOnly(new File(path));
}
return result;
}
/**
* 指定したディレクトリに保存されているファイルとディレクトリを全て削除します。<br>
* ただし、指定したディレクトリ自体は削除しません。
* @param dir 子ディレクトリと子ファイルを削除するディレクトリです。
* @return 削除が全て成功するとtrueを返します。一部でも削除できなかった場合、処理をすぐ中断し、falseを返します。<br>
* dirが存在しないか、ディレクトリでない場合もfalseを返します。
* @since 1.0.0
*/
public static boolean deleteChilds(File dir) {
boolean result = false;
if (dir != null && dir.exists() && dir.isDirectory()) {
File[] childs = dir.listFiles();
if (childs != null) {
for (File file : childs) {
result = delete(file);
if (!result) {
break;
}
}
}
}
return result;
}
/**
* 指定したディレクトリに保存されているファイルとディレクトリを全て削除します。<br>
* ただし、指定したディレクトリ自体は削除しません。
* @param dirPath 子ディレクトリと子ファイルを削除するディレクトリです。
* @return 削除が全て成功するとtrueを返します。一部でも削除できなかった場合、処理をすぐ中断し、falseを返します。<br>
* dirが存在しないか、ディレクトリでない場合もfalseを返します。
* @since 1.0.0
*/
public static boolean deleteChilds(String dirPath) {
boolean result = false;
if (!StringUtil.isNullOrWhiteSpace(dirPath)) {
result = deleteChilds(new File(dirPath));
}
return result;
}
// /**
// * ファイルをコピーします。
// * @param from コピー元のフィアルパスです。
// * @param to コピー先のファイルパスです。
// * @param overwrite コピー先のファイルが既に存在する場合、trueを設定すると上書きします。
// * @return コピーが成功するとtrueを返します。
// * @since 1.0.0
// */
// private static boolean copyFile(String from, String to, boolean overwrite) throws IOException {
// boolean result = false;
//
// if (!StringUtil.isNullOrWhiteSpace(from) && !StringUtil.isNullOrWhiteSpace(to) && !from.equals(to)) {
// result = copyFile(new File(from), new File(to), overwrite);
// }
//
// return result;
// }
/**
* ファイルをコピーします。
* @param from コピー元のフィアルパスです。
* @param to コピー先のファイルパスです。
* @param overwrite コピー先のファイルが既に存在する場合、trueを設定すると上書きします。
* @return コピーが成功するとtrueを返します。
* @throws IOException
* @since 1.0.0
*/
@SuppressWarnings("resource")
private static boolean copyFile(File from, File to, boolean overwrite) throws IOException {
boolean result = false;
if (from != null && to != null
&& from.exists() && !from.equals(to)
&& !from.isDirectory() && !to.isDirectory()) {
if (!to.exists() || overwrite) {
if (to.exists()) {
result = true;
} else {
if ((result = createParentDirectory(to.getPath()))) {
result = to.createNewFile();
}
}
if (result) {
FileChannel fromChannel = null;
FileChannel toChannel = null;
try {
fromChannel = new FileInputStream(from).getChannel();
toChannel = new FileOutputStream(to).getChannel();
// result = (toChannel.transferFrom(fromChannel, 0, fromChannel.size()) == fromChannel.size());
// 大サイズファイルのコピーは問題があるようで、 最大サイズを端末のmaxMemoryにする
// 実際のバッファーのサイズとコピー時のパフォーマンスは関係ないと確認 (1MB)
long maxMemory = (1024 * 1024);
Logger.d("FileUtil", "##copyFile start:fileSize=%sMB", (fromChannel.size() / 1024 / 1024));
long size = fromChannel.size(); // INファイルサイズ
long position = 0;
while (position < size) {
// コピー
position += fromChannel.transferTo(position, maxMemory, toChannel);
}
result = (position == fromChannel.size());
} catch (IOException e) {
result = false;
throw e;
} finally {
Logger.d("FileUtil", "copyFile end:result=%s", result);
if (fromChannel != null) {
fromChannel.close();
}
if (toChannel != null) {
toChannel.close();
}
}
}
}
}
return result;
}
/**
* ファイルをコピーする。
*
* 2G越えのファイルもコピー可
*/
public static boolean copyFileLarge(File from, File to) throws IOException {
InputStream is = null;
OutputStream os = null;
try {
is = new FileInputStream(from);
os = new FileOutputStream(to);
byte[] buffer = new byte[1024 * 4];
long count = 0;
int n;
while (-1 != (n = is.read(buffer))) {
os.write(buffer, 0, n);
count += n;
}
return from.length() == count;
} finally {
if (is != null) {
try {
is.close();
} catch (Exception e) {} // ignore
}
if (os != null) {
try {
os.close();
} catch (Exception e) {} // ignore
}
}
}
/**
* ファイル又はディレクトリをコピーします。
* @param from コピー元のパスです。
* @param to コピー先のパスです。
* @param overwrite コピー先がファイルであり、既に存在する場合、trueを設定すると上書きします。
* @return コピーが成功するとtrueを返します。
* @since 1.0.0
*/
public static boolean copy(String from, String to, boolean overwrite) throws IOException {
boolean result = false;
if (!StringUtil.isNullOrWhiteSpace(from) && !StringUtil.isNullOrWhiteSpace(to) && !from.equals(to)) {
result = copy(new File(from), new File(to), overwrite);
}
return result;
}
/**
* ファイル又はディレクトリをコピーします。
* @param from コピー元のパスです。
* @param to コピー先のパスです。
* @param overwrite コピー先がファイルであり、既に存在する場合、trueを設定すると上書きします。
* @return コピーが成功するとtrueを返します。
* @throws IOException
* @since 1.0.0
*/
public static boolean copy(File from, File to, boolean overwrite) throws IOException {
boolean result = false;
if (from != null && to != null && from.exists() && !from.equals(to)) {
if (from.isDirectory()) {
if (!(result = to.exists())) {
result = createNewDirectory(to.getPath());
}
if (result) {
String[] fromList = from.list();
if (fromList != null) {
for (String child : fromList) {
File fromChild = new File(from, child);
File toChild = new File(to, child);
result = copy(fromChild, toChild, overwrite);
if (!result) {
break;
}
}
}
}
} else {
if (from.length() < Integer.MAX_VALUE) {
result = copyFile(from, to, overwrite); // MemoryBlock.javaがInteger.MAX_VALUE以上のoffsetをエラーにするため巨大ファイルには適さない
}
else {
result = copyFileLarge(from, to);
}
}
}
return result;
}
/**
* ファイル又はディレクトリを移動します。
* @param from 移動元のフィアルパスです。
* @param to 移動先のファイルパスです。
* @param overwrite 移動先がファイルであり、既に存在する場合、trueを設定すると上書きします。
* @return 移動が成功するとtrueを返します。
* @since 1.0.0
*/
public static boolean move(String from, String to, boolean overwrite) {
boolean result = false;
if (!StringUtil.isNullOrWhiteSpace(from) && !StringUtil.isNullOrWhiteSpace(to) && !from.equals(to)) {
result = move(new File(from), new File(to), overwrite);
}
return result;
}
/**
* ファイルを移動します。
* @param from 移動元のフィアルパスです。
* @param to 移動先のファイルパスです。
* @param overwrite 移動先がファイルであり、既に存在する場合、trueを設定すると上書きします。
* @return 移動が成功するとtrueを返します。
* @since 1.0.0
*/
public static boolean move(File from, File to, boolean overwrite) {
boolean result = false;
if (from != null && to != null
&& from.exists() && !from.equals(to)) {
if (!to.exists() || overwrite) {
if (!to.exists()) {
createParentDirectory(to.getPath());
}
result = from.renameTo(to);
}
}
return result;
}
// /**
// * ファイル又はディレクトリを移動します。
// * @param from 移動元のパスです。
// * @param to 移動先のパスです。
// * @param overwrite 移動先がファイルであり、既に存在する場合、trueを設定すると上書きします。
// * @return 移動が成功するとtrueを返します。
// * @since 1.0.0
// */
// public static boolean move(String from, String to, boolean overwrite) throws IOException {
// boolean result = false;
//
// if (!StringUtil.isNullOrWhiteSpace(from) && !StringUtil.isNullOrWhiteSpace(to) && !from.equals(to)) {
// result = move(new File(from), new File(to), overwrite);
// }
//
// return result;
// }
//
// /**
// * ファイル又はディレクトリを移動します。
// * @param from 移動元のパスです。
// * @param to 移動先のパスです。
// * @param overwrite 移動先がファイルであり、既に存在する場合、trueを設定すると上書きします。
// * @return 移動が成功するとtrueを返します。
// * @since 1.0.0
// */
// public static boolean move(File from, File to, boolean overwrite) throws IOException {
// boolean result = false;
//
// if (from != null && to != null && from.exists() && !from.equals(to)) {
// if (from.isDirectory()) {
// if (!to.exists()) {
// result = createNewDirectory(to.getPath());
// }
//
// if (result) {
// for (String child : from.list()) {
// File fromChild = new File(from, child);
// File toChild = new File(to, child);
//
// result = move(fromChild, toChild, overwrite);
//
// if (!result) {
// break;
// }
// }
//
// delete(from);
// }
// } else {
// result = moveFile(from, to, overwrite);
// }
// }
//
// return result;
// }
/**
* 指定したファイルが既に存在するとファイル名の後ろに2桁の番号をつけたファイル名を作成します。番号は01から99までであり、99を超えるとファイル名の後ろに-rをつけます。<br>
* 例:file.txt、file-01.txt、file-02.txt...file-99.txt、file-r.txt、file-r-01.txt...file-r-99.txt、file-r-r.txt
* @param filePath テストするファイル名です。
* @return 指定したファイルが存在しないとそのままを、存在する場合は、番号付のファイル名を返します。
* @since 1.0.0
*/
public static String getWritableFileName(String filePath) {
String newFilePath = StringUtil.Empty;
if (!StringUtil.isNullOrWhiteSpace(filePath)) {
File file = new File(filePath);
if (file.exists()) {
if (file.isFile()) {
final String parentPath = getParentPath(filePath);
final String fileNameWithouExt = getFilenameWithoutExt(filePath);
final String extension = getExtension(filePath);
File dir = new File(parentPath);
String[] files = dir.list(new FilenameFilter() {
@Override
public boolean accept(File dir, String file) {
String filenameWithoutExt = getFilenameWithoutExt(file);
return (file.startsWith(fileNameWithouExt) && getExtension(file).equals(extension)
&& filenameWithoutExt.matches(RegexRotationFileNameWithoutExt));
}
});
int max = 0;
if (files != null) {
for (String f : files) {
String name = getFilenameWithoutExt(f);
String strNum = name.substring(name.length() - 2);
int nNum = NumericUtil.parseInt(strNum);
if (nNum > max) {
max = nNum;
}
}
}
max++;
if (max >= 100) {
newFilePath = String.format("%s%s-r.%s", parentPath, fileNameWithouExt, extension);
newFilePath = getWritableFileName(newFilePath);
} else {
newFilePath = String.format("%s%s-%02d.%s", parentPath, fileNameWithouExt, max, extension);
}
}
} else {
newFilePath = filePath;
}
}
return newFilePath;
}
/**
* 指定したディレクトリが既に存在するとディレクトリ名の後ろに2桁の番号をつけたディレクトリ名を作成します。番号は01から99までであり、99を超えるとファイル名の後ろに-rをつけます。<br>
* 例:dir、dir-01、dir-02...dir-99、dir-r、dir-r-01...dir-r-99、dir-r-r
* @param dirPath テストするディレクトリ名です。
* @return 指定したディレクトリが存在しないとそのままを、存在する場合は、番号付のディレクトリ名を返します。
* @since 1.0.0
*/
public static String getWritableDirectoryName(final String dirPath) {
return getWritableDirectoryName(dirPath, false);
}
public static String getWritableDirectoryName(final String dirPath, boolean forceNext) {
String newFilePath = StringUtil.Empty;
if (!StringUtil.isNullOrWhiteSpace(dirPath)) {
final File dir = new File(dirPath);
if (dir.exists() || forceNext) {
if (dir.isDirectory() || forceNext) {
final String parentPath = getParentPath(dirPath);
File parentDir = new File(parentPath);
String[] files = parentDir.list(new FilenameFilter() {
@Override
public boolean accept(File f, String s) {
return (s.startsWith(dir.getName())
&& s.matches(RegexRotationFileNameWithoutExt));
}
});
int max = 0;
if (files != null) {
for (String f : files) {
String name = getFilenameWithoutExt(f);
String strNum = name.substring(name.length() - 2);
int nNum = NumericUtil.parseInt(strNum);
if (nNum > max) {
max = nNum;
}
}
}
max++;
if (max >= 100) {
newFilePath = String.format("%s%s-r", parentPath, dirPath);
newFilePath = getWritableFileName(newFilePath);
} else {
newFilePath = String.format("%s%s-%02d", parentPath, dirPath, max);
}
}
} else {
newFilePath = dirPath;
}
}
return newFilePath;
}
public static long getFileSize(String filePath) {
if (StringUtil.isNullOrWhiteSpace(filePath)) {
return 0L;
} else {
return new File(filePath).length();
}
}
public static File[] getChildDirectories(String dirPath) {
if (StringUtil.isNullOrWhiteSpace(dirPath)) {
return null;
} else {
return getChildDirectories(new File(dirPath));
}
}
public static File[] getChildDirectories(File dir) {
File[] childs = null;
if (dir != null && dir.exists() && dir.isDirectory()) {
childs = dir.listFiles(new FileFilter() {
@Override
public boolean accept(File f) {
return f.isDirectory();
}
});
}
return childs;
}
public static File[] getChildFiles(File dir) {
if (dir.exists()) {
return dir.listFiles();
}
else {
return null;
}
}
public static boolean exists(String path) {
if (path == null) {
return false;
}
return new File(path).exists();
}
public static boolean hasSize(String path) {
File file = new File(path);
return file.exists() && file.length() > 0;
}
public static String readTextFile(String path) throws IOException {
File file = new File(path);
if (file.length() == 0) {
return null; // TODO: later 暫定処置 とりあえずこのまま
// throw new FileNotFoundException(path);
}
return readTextFile(new FileInputStream(file));
}
public static String readTextFile(InputStream is) throws IOException {
StringBuffer text = new StringBuffer();
try {
int bufferSize = 2048;
int readSize;
byte[] buffer = new byte[bufferSize];
while ((readSize = is.read(buffer, 0, buffer.length)) > 0) {
text.append(new String(buffer, 0, readSize));
}
return text.toString();
}
finally {
if (is != null) {
try {
is.close();
} catch (Exception e2) {
}
}
}
}
// public static void saveZip(String outFile, String password, String... inputFiles) throws ZipException, IOException, NoSuchAlgorithmException{
// ZipOutputStream os = null;
// InputStream is = null;
//
// try {
// ArrayList<File> filesToAdd = new ArrayList<File>();
// for (String inputFile : inputFiles) {
// filesToAdd.add(new File(inputFile));
// }
//
// os = new ZipOutputStream(new FileOutputStream(new File(outFile)));
// ZipParameters parameters = new ZipParameters();
// parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
// parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
// if (!StringUtil.isNullOrEmpty(password)) {
// parameters.setEncryptFiles(true);
// parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_AES);
// parameters.setAesKeyStrength(Zip4jConstants.AES_STRENGTH_256);
// parameters.setPassword(password);
// }
// for (int i = 0; i < filesToAdd.size(); i++) {
// File file = filesToAdd.get(i);
// os.putNextEntry(file, parameters);
// if (file.isDirectory()) {
// os.closeEntry();
// continue;
// }
// is = new FileInputStream(file);
// byte[] readBuff = new byte[4096];
// int readLen;
//
// while ((readLen = is.read(readBuff)) != -1) {
// os.write(readBuff, 0, readLen);
// }
// os.closeEntry();
// is.close();
// }
// os.finish();
//
// } finally {
// if (os != null) {
// try {
// os.close();
// } catch (IOException e) {
// }
// }
//
// if (is != null) {
// try {
// is.close();
// } catch (IOException e) {
// }
// }
// }
// }
public static void saveProcessOut(Process process, String outPath) throws IOException {
InputStreamReader is = null;
OutputStreamWriter ow = null;
try {
is = new InputStreamReader(process.getInputStream());
ow = new OutputStreamWriter(new FileOutputStream(outPath), "UTF-8");
int contents;
while ((contents = is.read()) != -1) {
ow.write(contents);
}
is.close();
ow.close();
}
finally {
if (is != null) {
try {
is.close();
} catch (Exception e2) {
}
}
if (ow != null) {
try {
ow.close();
} catch (Exception e2) {
}
}
try {
if (process != null) {
process.destroy();
}
} catch (Exception e) {
}
}
}
/**
* 指定内容のテキストファイルを作成する。
*
* @param path
* @param content
* @throws IOException
*/
public static void createFile(String path, String content) throws IOException {
FileOutputStream out = null;
try {
File file = new File(path);
// パス上の上位フォルダが存在しない、または同名のファイル名が存在する場合
if (!file.getParentFile().exists() || !file.getParentFile().isDirectory()) {
file.getParentFile().mkdirs();
}
out = new FileOutputStream(file);
out.write(content.getBytes());
out.flush();
}
finally {
if (out != null) {
out.close();
}
}
}
/**
* 指定ファイルの先頭指定バイトを16進数表示するための文字列を返す
*
* @param path
* @param length
* @throws IOException
*/
public static String getHexDump(String path, int length) throws IOException {
FileInputStream fs = null;
try {
fs = new FileInputStream(path);
byte[] buf = new byte[length];
fs.read(buf);
StringBuffer sb = new StringBuffer();
for (int i=0; i < buf.length; i++) {
if (i > 0 && i % 16 == 0) {
sb.append("\n");
}
sb.append(String.format("%02x", buf[i] & 0xff));
sb.append(" ");
}
return sb.toString();
}
finally {
if (fs != null) {
try {
fs.close();
} catch (IOException e) {
Logger.e("FileUtil", "getHexDump FileInputStream close error.", e);
}
}
}
}
}
package jp.odakyu.toiletsignage.util;
/**
* 数字型を扱う機能を提供します。
* @author Taejin Hong
* @version 1.0.0
*/
public class NumericUtil {
/**
* 指定したクラスが数字型かどうかを示します。
* @param type テストするクラスです。
* @return typeがBigDecimal, BigInteger, Byte, Double, Float, Integer, Long, Short又はbyte, double, float, int, long, shortのクラスだとtrueを返します。
* @see Number
* @since 1.0.0
*/
public static boolean isNumberType(Class<?> type) {
boolean isNumber = false;
if (type != null) {
if ((type.getSuperclass() != null && type.getSuperclass().equals(Number.class))
|| type.equals(int.class) || type.equals(long.class) || type.equals(double.class)
|| type.equals(float.class) || type.equals(byte.class) || type.equals(short.class)) {
isNumber = true;
}
}
return isNumber;
}
/**
* 指定した値が数字かどうかを示します。
* @param value テストする値です。
* @return valueが数字であればtrueを返します。
* @since 1.0.0
*/
@Deprecated
public static boolean isNumber(Object value) {
boolean isNumber = false;
if (value != null) {
isNumber = (value instanceof Number || isNumberType(value.getClass()));
}
return isNumber;
}
/**
* 指定した文字列をint型に変換します。
* @param s 数字に変換する文字列です。
* @return 変換した数字を返します。文字列が数字に変換することができない場合、0を返します。
* @since 1.0.0
*/
public static int parseInt(String s) {
return parseInt(s, 0);
}
/**
* 指定した文字列をint型に変換します。
* @param s 数字に変換する文字列です。
* @param defaultValue 文字列が数字に変換することができない場合、使用するデフォルト値です。
* @return 変換した数字を返します。文字列が数字に変換することができない場合、defaultValueを返します。
* @since 1.0.0
*/
public static int parseInt(String s, int defaultValue) {
int result = defaultValue;
if (!StringUtil.isNullOrWhiteSpace(s)) {
try {
result = Integer.parseInt(s);
} catch (Exception e) {
}
}
return result;
}
/**
* {@link Integer} 型をint型に変換します。
* @param n 変換する数字です。
* @return 変換した数字を返します。nがnullである場合、0を返します。
* @since 1.0.0
*/
public static int parseInt(Integer n) {
return parseInt(n, 0);
}
/**
* {@link Integer} 型をint型に変換します。
* @param n 変換する数字です。
* @param defaultValue nがnullである場合、使用するデフォルト値です。
* @return 変換した数字を返します。nがnullである場合、defaultValueを返します。
* @since 1.0.0
*/
public static int parseInt(Integer n, int defaultValue) {
if (n != null) {
return n;
} else {
return defaultValue;
}
}
/**
* 指定した文字列をlong型に変換します。
* @param s 数字に変換する文字列です。
* @return 変換した数字を返します。文字列が数字に変換することができない場合、0を返します。
* @since 1.0.0
*/
public static long parseLong(String s) {
return parseLong(s, 0);
}
/**
* 指定した文字列をlong型に変換します。
* @param s 数字に変換する文字列です。
* @param defaultValue 文字列が数字に変換することができない場合、使用するデフォルト値です。
* @return 変換した数字を返します。文字列が数字に変換することができない場合、defaultValueを返します。
* @since 1.0.0
*/
public static long parseLong(String s, int defaultValue) {
long result = defaultValue;
if (!StringUtil.isNullOrWhiteSpace(s)) {
try {
result = Long.parseLong(s);
} catch (Exception e) {
}
}
return result;
}
/**
* {@link Long} 型をint型に変換します。
* @param n 変換する数字です。
* @return 変換した数字を返します。nがnullである場合、0を返します。
* @since 1.0.0
*/
public static long parseInt(Long n) {
return parseInt(n, 0);
}
/**
* {@link Long} 型をint型に変換します。
* @param n 変換する数字です。
* @param defaultValue nがnullである場合、使用するデフォルト値です。
* @return 変換した数字を返します。nがnullである場合、defaultValueを返します。
* @since 1.0.0
*/
public static long parseInt(Long n, int defaultValue) {
if (n != null) {
return n;
} else {
return defaultValue;
}
}
/**
* {@link Boolean} 型をint型に変換します。
* @param b 変換する値です。
* @return 変換した数字を返します。bがnullである場合、0を返します。
* @since 1.0.0
*/
public static int parseInt(Boolean b) {
if (b != null) {
return (b ? 1 : 0);
} else {
return 0;
}
}
/**
* 指定した文字列をshort型に変換します。
* @param s 数字に変換する文字列です。
* @return 変換した数字を返します。文字列が数字に変換することができない場合、0を返します。
* @since 1.0.0
*/
public static short parseShort(String s) {
return parseShort(s, (short)0);
}
/**
* 指定した文字列をshort型に変換します。
* @param s 数字に変換する文字列です。
* @param defaultValue 文字列が数字に変換することができない場合、使用するデフォルト値です。
* @return 変換した数字を返します。文字列が数字に変換することができない場合、defaultValueを返します。
* @since 1.0.0
*/
public static short parseShort(String s, short defaultValue) {
short result = defaultValue;
if (!StringUtil.isNullOrWhiteSpace(s)) {
try {
result = Short.parseShort(s);
} catch (Exception e) {
}
}
return result;
}
/**
* {@link Short} 型をshort型に変換します。
* @param n 変換する数字です。
* @return 変換した数字を返します。nがnullである場合、0を返します。
* @since 1.0.0
*/
public static short parseShort(Short n) {
return parseShort(n, (short)0);
}
/**
* {@link Short} 型をshort型に変換します。
* @param n 変換する数字です。
* @param defaultValue nがnullである場合、使用するデフォルト値です。
* @return 変換した数字を返します。nがnullである場合、defaultValueを返します。
* @since 1.0.0
*/
public static short parseShort(Short n, short defaultValue) {
if (n != null) {
return n;
} else {
return defaultValue;
}
}
}
package jp.odakyu.toiletsignage.util;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLEncoder;
import java.text.NumberFormat;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 文字列を扱うための便利機能を提供します。
* @author macrojin
* @version 1.0.1
*/
public class StringUtil {
/**
* 空の文字列を表します。 このフィールドは読み取り専用です。<br>
* このフィールドの値は、長さ 0 の文字列 "" です。
* @since 1.0.0
*/
public static final String Empty = "";
/**
* 空白(スペース)文字列を示します。このフィールドは読み取り専用です。
* @since 1.0.0
*/
public static final String Space = " ";
/**
* キャリッジリターン(CR)文字の\rです。このフィールドは読み取り専用です。
* @since 1.0.0
*/
public static final String CarriageReturn = "\r";
/**
* ラインフィード(LF)文字の\nです。このフィールドは読み取り専用です。
* @since 1.0.0
*/
public static final String LineFeed = "\n";
/**
* CRLFをあわせたものです。
* @since 1.0.1
*/
public static final String CRLF = CarriageReturn + LineFeed;
/**
* スラッシュ文字です。
* @since 1.0.0
*/
public static final String Slash = "/";
public static final String BackSlash = "\\";
public static final String Hyphen = "-";
public static final String QuestionMark = "?";
private static final String RegexBriceL = "[";
private static final String RegexBriceR = "]";
private static final String RegexPlus = "+";
private static final String RegexAlphabet = "a-zA-Z";
private static final String RegexNumeric = "0-9";
private static final String RegexTrimLastSlashOrSpace = "[/ ]+$";
private static String ELLIPSIS = "...";
/**
* 指定された文字列が null または {@link StringUtil#Empty} 文字列であるかどうかを示します。
* @param s テストする文字列。
* @return s パラメーターが null または空の文字列 ("") の場合は true。それ以外の場合は false。
* @since 1.0.0
*/
public static boolean isNullOrEmpty(String s) {
return s == null || s.equals(Empty);
}
/**
* 指定された文字列が null または {@link StringUtil#Empty} 文字列であるかどうかを示します。
* @param s テストする文字列。
* @return パラメーターが null または空の文字列 ("") の場合は true。それ以外の場合は false。
* @since 1.0.0
*/
public static boolean isNullOrEmpty(StringBuffer s) {
return s == null || isNullOrEmpty(s.toString());
}
/**
* 指定された文字列が null または {@link StringUtil#Empty} 文字列であるかどうかを示します。
* @param s テストする文字列。
* @return パラメーターが null または空の文字列 ("") の場合は true。それ以外の場合は false。
* @since 1.0.0
*/
public static boolean isNullOrEmpty(StringBuilder s) {
return s == null || isNullOrEmpty(s.toString());
}
/**
* 指定された文字列が null または空であるか、空白文字だけで構成されているかどうかを示します。
* @param s テストする文字列。
* @return s パラメーターが null または {@link StringUtil#Empty} であるか、s が空白文字だけで構成されている場合は true。
* @since 1.0.0
*/
public static boolean isNullOrWhiteSpace(String s) {
return isNullOrEmpty(s) || s.trim().length() == 0;
}
/**
* 指定された文字列が null または空であるか、空白文字だけで構成されているかどうかを示します。
* @param s テストする文字列。
* @return s パラメーターが null または {@link StringUtil#Empty} であるか、s が空白文字だけで構成されている場合は true。
* @since 1.0.0
*/
public static boolean isNullOrWhiteSpace(StringBuffer s) {
return isNullOrEmpty(s) || s.toString().trim().length() == 0;
}
/**
* 指定された文字列が null または空であるか、空白文字だけで構成されているかどうかを示します。
* @param s テストする文字列。
* @return s パラメーターが null または {@link StringUtil#Empty} であるか、s が空白文字だけで構成されている場合は true。
* @since 1.0.0
*/
public static boolean isNullOrWhiteSpace(StringBuilder s) {
return isNullOrEmpty(s) || s.toString().trim().length() == 0;
}
/**
* オブジェクトを文字列に変換します。変換には {@link Object#toString()} を利用します。
* @param obj 変換するオブジェクトです。
* @return 変換した文字列を返します。変換できない場合、又は変換した文字列が空文字である場合、{@link StringUtil#Empty} を返します。。
* @since
*/
public static String toString(Object obj) {
return toString(obj, Empty);
}
/**
* オブジェクトを文字列に変換します。変換には {@link Object#toString()} を利用します。
* @param obj 変換するオブジェクトです。
* @param defaultValue 変換できない場合、又は変換した文字列が空文字である場合、使用するデフォルト値です。
* @return 変換した文字列を返します。変換できない場合、又は変換した文字列が空文字である場合、defaultValueを返します。
* @since
*/
public static String toString(Object obj, String defaultValue) {
if (obj != null && !isNullOrEmpty(obj.toString())) { // Comment: toStringを2度呼んでいるためパフォーマンスが低下
return obj.toString();
} else {
return defaultValue;
}
}
/**
* 指定された文字列を空にします。
* @param s 空にする文字列
* @since 1.0.0
*/
public static void clear(StringBuffer s) {
if (!isNullOrEmpty(s) && s.length() > 0) {
s.delete(0, s.length());
}
}
/**
* 指定された文字列を空にします。
* @param s 空にする文字列
* @since 1.0.0
*/
public static void clear(StringBuilder s) {
if (!isNullOrEmpty(s) && s.length() > 0) {
s.delete(0, s.length());
}
}
/**
* 文字列の最後を改行します。
* @param s 改行する文字列
* @since 1.0.0
*/
public static void appendLine(StringBuffer s) {
s.append(StringUtil.LineFeed);
}
/**
* 文字列の最後を改行します。
* @param s 改行する文字列
* @since 1.0.0
*/
public static void appendLine(StringBuilder s) {
s.append(StringUtil.LineFeed);
}
/**
* 文字列 s に複数の文字列を追加し、改行します。
* @param s 改行する文字列
* @param arg 追加する文字列
* @since 1.0.0
*/
public static void appendLine(StringBuffer s, String arg) {
s.append(arg);
appendLine(s);
}
/**
* 文字列 s に複数の文字列を追加し、改行します。
* @param s 改行する文字列
* @param arg 追加する文字列
* @since 1.0.0
*/
public static void appendLine(StringBuilder s, String arg) {
s.append(arg);
appendLine(s);
}
/**
* 文字列 s に複数の文字列を追加し、改行します。
* @param s 改行する文字列
* @param args 追加する文字列
* @since 1.0.0
*/
public static void appendMultiLine(StringBuffer s, String...args) {
for (String string : args) {
appendLine(s, string);
}
}
/**
* 文字列 s に複数の文字列を追加し、改行します。
* @param s 改行する文字列
* @param args 追加する文字列
*
* @since 1.0.0
*/
public static void appendMultiLine(StringBuilder s, String...args) {
for (String string : args) {
appendLine(s, string);
}
}
/**
* 文字列 s に複数の文字列を追加し、改行します。
* @param s 改行する文字列
* @param arg 追加する文字列
* @since 1.0.0
*/
public static void appendLine(StringBuffer s, int arg) {
s.append(arg);
appendLine(s);
}
/**
* 文字列 s に複数の文字列を追加し、改行します。
* @param s 改行する文字列
* @param arg 追加する文字列
* @since 1.0.0
*/
public static void appendLine(StringBuilder s, int arg) {
s.append(arg);
appendLine(s);
}
/**
* 文字列 s に複数の文字列を追加し、改行します。
* @param s 改行する文字列
* @param arg 追加する文字列
* @since 1.0.0
*/
public static void appendLine(StringBuffer s, long arg) {
s.append(arg);
appendLine(s);
}
/**
* 文字列 s に複数の文字列を追加し、改行します。
* @param s 改行する文字列
* @param arg 追加する文字列
* @since 1.0.0
*/
public static void appendLine(StringBuilder s, long arg) {
s.append(arg);
appendLine(s);
}
/**
* 文字列 s に複数の文字列を追加し、改行します。
* @param s 改行する文字列
* @param arg 追加する文字列
* @since 1.0.0
*/
public static void appendLine(StringBuffer s, Object arg) {
s.append(arg);
appendLine(s);
}
/**
* 文字列 s に複数の文字列を追加し、改行します。
* @param s 改行する文字列
* @param arg 追加する文字列
* @since 1.0.0
*/
public static void appendLine(StringBuilder s, Object arg) {
s.append(arg);
appendLine(s);
}
/**
* 指定した文字列を指定した区切りで分割します。分割時にtrimを行います。<br>
* 空白の要素は戻り値から省かれます。
* @param source 分割する文字列です。
* @param delimiter 分割の区切りです。
* @return 分割された文字列の配列を返します。
* @since 1.0.0
*/
public static String[] split(String source, String delimiter) {
return split(source, delimiter, true);
}
/**
* 指定した文字列を指定した区切りで分割します。
* @param source 分割する文字列です。
* @param delimiter 分割の区切りです。
* @param ignoreEmpty trueにすると、空白の要素は戻り値から省かれます。
* @return 分割された文字列の配列を返します。
* @since 1.0.0
*/
public static String[] split(String source, String delimiter, boolean ignoreEmpty) {
String[] result = new String[]{source};
if (!isNullOrWhiteSpace(source)) {
String pattern;
if (ignoreEmpty) {
pattern = delimiter + "\\s+|" + delimiter;
} else {
pattern = delimiter + "\\s|" + delimiter;
}
result = source.split(pattern);
}
return result;
}
/**
* 指定した文字列が正しいURLであるかどうかを示します。
* @param url テストするURL文字列です。
* @return 文字列が正常なURLを示すとtrueを返します。
* @since 1.0.0
*/
public static boolean validateUrlString(String url) {
boolean result = true;
try {
//noinspection ResultOfObjectAllocationIgnored
new URL(url);
} catch (Exception e) {
result = false;
}
return result;
}
/**
* 指定したURL文字列の後端に/が付いていなければ、/を付けます。<br>
* この際、文字列が正しいURLであるかどうかを確認し、有効なURLではない場合、nullを返します。
* @param url URL文字列です。
* @return 後端に/を付けたURL文字列です。
* @since 1.0.0
*/
public static String addSlashToUrlString(String url) {
String result = null;
if (validateUrlString(url)) {
String temp = url.trim();
if (!temp.endsWith("/")) {
temp += "/";
}
result = temp;
}
return result;
}
/**
* 指定した文字列が半角文字だけで構成されているかどうかを示します。
* @param s テストする文字列です。
* @param allowAlphabet trueにすると半角英字を許容します。
* @param allowNumeric trueにすると半角数字を許容します。
* @param allowSymbols 英数字以外に許容したい記号を指定します。たとえば、文字列にスペースを許容したい場合、ここにスペースを指定します。この記号が半角かどうかは判別しません。
* @return sが指定した条件に合致するとtrueを返します。
* @since 1.0.0
*/
public static boolean isHankaku(String s, boolean allowAlphabet, boolean allowNumeric, String...allowSymbols) {
boolean result = false;
StringBuffer pattern = new StringBuffer();
if (!isNullOrEmpty(s)
&& (allowAlphabet
|| allowNumeric
|| (allowSymbols != null && allowSymbols.length > 0)
)
) {
pattern.append(RegexBriceL);
if (allowAlphabet) {
pattern.append(RegexAlphabet);
}
if (allowNumeric) {
pattern.append(RegexNumeric);
}
if (allowSymbols != null && allowSymbols.length > 0) {
for (String symbol : allowSymbols) {
if (symbol.equals(Hyphen) || symbol.equals(BackSlash)) {
pattern.append(BackSlash);
pattern.append(symbol);
} else {
pattern.append(symbol);
}
}
}
pattern.append(RegexBriceR);
pattern.append(RegexPlus);
result = s.matches(pattern.toString());
}
return result;
}
/**
* 指定した文字列の最後についている/又は空白を除去します。/又は空白が複数あっても最後であれば全て除去します。
* @param s 最後の/又は空白を除去する文字列です。
* @return 最後の/又は空白を除去した文字列を返します。
* @since 1.0.0
*/
public static String trimLastSlashOrSpace(String s) {
String result = null;
if (!StringUtil.isNullOrEmpty(s)) {
result = s.replaceAll(RegexTrimLastSlashOrSpace, Empty);
}
return result;
}
/**
* 指定した複数の文字列sをdelimiterを区切りとして結合します。
* @param delimiter 文字列と文字列の区切りです。(カンマ、コロン、空白等)
* @param s 結合する文字列の配列です。
* @return 結合した文字列を返します。
* @since 1.0.0
*/
public static String join(String delimiter, String...s) {
StringBuffer sb = new StringBuffer();
if (s != null && s.length > 0) {
if (delimiter == null) {
delimiter = Empty;
}
for (int i = 0; i < s.length; i++) {
sb.append(s[i]);
if (i < s.length - 1) {
sb.append(delimiter);
}
}
}
return sb.toString();
}
public static String join(String delimiter, List<?> list) {
StringBuffer sb = new StringBuffer();
if (list != null && !list.isEmpty()) {
if (delimiter == null) {
delimiter = Empty;
}
for (int i = 0; i < list.size(); i++) {
sb.append(list.get(i));
if (i < list.size() - 1) {
sb.append(delimiter);
}
}
}
return sb.toString();
}
/**
* 数字を3桁ごとのカンマ区切りの文字列に変換して返却します。
*
* @param num
* @return
*/
public static String numberDispFormatComma(Integer num) {
if (num == null) {
return "";
}
NumberFormat numberFormat = NumberFormat.getNumberInstance();
return numberFormat.format(num);
}
/**
* 指定配列に指定文字列が含まれるかどうかを返す
*
* @param search
* @param array
* @return
*/
public static boolean contains(String search, String[] array) {
if (search == null || array == null || array.length == 0) {
return false;
}
for (String string : array) {
if (string != null && string.equals(search)) {
return true;
}
}
return false;
}
public static String urlEncode(String s, String enc) throws Exception {
if (s == null) {
return null;
}
try {
return URLEncoder.encode(s, enc).replace("+", "%20");
} catch (UnsupportedEncodingException e) {
throw new Exception(e);
}
}
public static boolean isNumber(String s) {
try {
Long.parseLong(s);
return true;
} catch (Exception e) {
return false;
}
}
public static boolean isReal(String s) {
try {
Double.parseDouble(s);
return true;
} catch (Exception e) {
return false;
}
}
public static String chomp(String str) {
if (str != null && (str.endsWith("\n") || str.endsWith("\r"))) {
str = str.substring(0, str.length() - 1);
}
return str;
}
/**
* 正規表現にしたがって文字列を抽出する
*
* @param src 対象文字列
* @param regex 正規表現
* @param index 正規表現中の抽出対象となる()の番号
* @return ヒットした最初の文字列
*/
public static String extractRegexString(String src, String regex, int index) {
Pattern regx = Pattern.compile(regex);
Matcher m = regx.matcher(src);
if (m.find()) {
return m.group(index);
}
return null;
}
/**
* 正規表現にしたがって文字列(複数)を抽出する
*
* @param src 対象文字列
* @param regex 正規表現
* @param index 正規表現中の抽出対象となる()の番号(配列)
* @return ヒットしたすべての文字列リスト
*/
public static List<List<String>> extractRegexString(String src, String regex, int[] index) {
Pattern regx = Pattern.compile(regex);
List<List<String>> list = new LinkedList<List<String>>();
Matcher m = regx.matcher(src);
while (m.find()) {
List<String> matchList = new LinkedList<String>();
for (int element : index) {
matchList.add(m.group(element));
}
list.add(matchList);
}
return list;
}
public static boolean equals(String s1, String s2) {
if (s1 == null) {
return s2 == null;
}
else {
return s1.equals(s2);
}
}
/**
* 第一引数に、第二引数以降のいずれかが一致した場合trueを返す
*
* @param s
* @param targets
* @return
*/
public static boolean equalsAny(String s, String... targets) {
for (String target : targets) {
if (equals(s, target)) {
return true;
}
}
return false;
}
/**
* 指定文字列に、第二引数以降の文字列のいずれかで終わっているか
*
* @param target
* @param anys
* @return
*/
public static boolean endsWithAny(String target, String ...anys) {
if (target == null || anys == null || anys.length == 0) {
return false;
}
for (String any : anys) {
if (target.endsWith(any)) {
return true;
}
}
return false;
}
/**
* 文字列長が指定したmaxlengthを越えないように適宜省略する
* @param str 表示される文字列
* @param maxlength 許容される最大長
* @return
*/
public static String abbreviate(String str, int maxlength) {
/* パラメータ補正 */
if (str == null) {
str = "";
}
if (maxlength < ELLIPSIS.length()) {
/* ワーストケースでは ... となるため最低3文字必要 */
throw new IllegalArgumentException("maxlength is too small");
}
final int len = str.length();
if (len <= maxlength) {
return str;
} else if (len > ELLIPSIS.length()) {
return str.substring(0, maxlength - ELLIPSIS.length()) + ELLIPSIS;
} else {
return ELLIPSIS;
}
}
public static boolean startsWith(String str, String target) {
if (isNullOrEmpty(str) || isNullOrEmpty(target)) {
return false;
}
return str.startsWith(target);
}
}
......@@ -105,7 +105,7 @@
android:id="@+id/vacantTitleENTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/total_en"
android:text="@string/vacant_en"
android:textAlignment="center"
android:textColor="#746661"
android:textSize="30sp"
......
......@@ -47,7 +47,7 @@
<View
android:id="@+id/separator"
android:layout_width="match_parent"
android:layout_height="3dip"
android:layout_height="4dip"
android:layout_marginEnd="50dp"
android:layout_marginStart="50dp"
......@@ -209,6 +209,7 @@
android:layout_marginBottom="1dp"
android:layout_marginTop="20dp"
android:layout_weight="1"
android:paddingEnd="60dp"
android:text="@string/near_toilet_info_jp"
android:textAlignment="textEnd"
android:textColor="@android:color/white"
......@@ -222,16 +223,17 @@
android:layout_marginBottom="1dp"
android:layout_marginTop="20dp"
android:layout_weight="1"
android:paddingStart="10dp"
android:text="@string/near_toilet_info_en"
android:textAlignment="textStart"
android:textColor="@android:color/white"
android:textSize="35sp" />
android:textSize="37sp" />
</LinearLayout>
<View
android:id="@+id/separator3"
android:layout_width="match_parent"
android:layout_height="3dip"
android:layout_height="4dip"
android:layout_marginEnd="50dp"
android:layout_marginStart="50dp"
android:background="#FFFFFF" />
......@@ -265,8 +267,7 @@
android:textAlignment="center"
android:textColor="@android:color/white"
android:textSize="40sp"
android:textStyle="bold"
/>
android:textStyle="bold" />
<TextView
android:id="@+id/leftGateNameENTextView"
......@@ -291,11 +292,11 @@
<View
android:id="@+id/separator4"
android:layout_width="3dip"
android:layout_width="4dip"
android:layout_height="match_parent"
android:layout_marginStart="10dp"
android:layout_marginTop="15dp"
android:layout_marginBottom="15dp"
android:layout_marginStart="20dp"
android:layout_marginTop="18dp"
android:layout_marginBottom="18dp"
android:background="#FFFFFF" />
</LinearLayout>
......@@ -317,6 +318,7 @@
android:id="@+id/rightGateNameJPTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:ellipsize="end"
android:singleLine="true"
android:maxLines="1"
......@@ -330,6 +332,7 @@
android:id="@+id/rightGateNameENTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:ellipsize="end"
android:singleLine="true"
android:text="@string/right_toilet_info_en"
......@@ -343,6 +346,7 @@
android:id="@+id/rightStatusIconImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginEnd="50dp"
android:layout_marginTop="22dp"
app:srcCompat="@drawable/icon_full_sub" />
......
......@@ -9,7 +9,7 @@
<string name="total_jp">総数</string>
<string name="total_en">TOTAL</string>
<string name="near_toilet_info_jp">お近くのトイレ情報</string>
<string name="near_toilet_info_en"> Other Toilets Nearby</string>
<string name="near_toilet_info_en">Other Toilets Nearby</string>
<string name="left_toilet_info_jp">西口地下改札外</string>
<string name="left_toilet_info_en">The West Underground Gate(Outside)</string>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment