4 import java.awt.Color;
\r
5 import java.awt.Desktop;
\r
6 import java.beans.XMLDecoder;
\r
7 import java.beans.XMLEncoder;
\r
8 import java.io.BufferedInputStream;
\r
9 import java.io.BufferedOutputStream;
\r
10 import java.io.BufferedReader;
\r
11 import java.io.BufferedWriter;
\r
12 import java.io.File;
\r
13 import java.io.FileInputStream;
\r
14 import java.io.FileNotFoundException;
\r
15 import java.io.FileOutputStream;
\r
16 import java.io.FileReader;
\r
17 import java.io.FileWriter;
\r
18 import java.io.IOException;
\r
19 import java.io.InputStream;
\r
20 import java.io.InputStreamReader;
\r
21 import java.io.OutputStream;
\r
22 import java.io.OutputStreamWriter;
\r
23 import java.io.Reader;
\r
24 import java.io.Writer;
\r
25 import java.net.HttpURLConnection;
\r
26 import java.net.Socket;
\r
27 import java.nio.channels.FileChannel;
\r
28 import java.nio.channels.FileLock;
\r
29 import java.text.SimpleDateFormat;
\r
30 import java.util.ArrayList;
\r
31 import java.util.Calendar;
\r
32 import java.util.GregorianCalendar;
\r
33 import java.util.HashMap;
\r
34 import java.util.Map.Entry;
\r
35 import java.util.regex.Matcher;
\r
36 import java.util.regex.Pattern;
\r
37 import java.util.zip.ZipEntry;
\r
38 import java.util.zip.ZipFile;
\r
39 import java.util.zip.ZipOutputStream;
\r
42 * <P>頻繁に使用する雑多なメソッドをstaticで提供します。
\r
43 * <P>パッケージを小分けにしておけばよかった…
\r
45 public class CommonUtils {
\r
47 /*******************************************************************************
\r
49 ******************************************************************************/
\r
54 public static void setDebug(boolean b) { debug = b; }
\r
55 private static boolean debug = false;
\r
56 private static boolean debuglv2 = false; // これは俺用
\r
61 public static void setAdjLateNight(boolean b) { adjLateNight = b; }
\r
62 private static boolean adjLateNight = false;
\r
65 * Web番組表の8日分取得に対応するかどうか
\r
67 public static void setExpandTo8(boolean b) { dogDays = ((b)?(8):(7)); }
\r
68 private static int dogDays = 7;
\r
73 public static void setDisplayPassedReserve(boolean b) { displayPassedReserve = b; }
\r
74 private static boolean displayPassedReserve = false;
\r
77 * Windows環境下で、アプリケーションに関連付けられたファイルを開くのにrundll32.exeを利用するかどうか
\r
79 public static void setUseRundll32(boolean b) { useRundll32 = b; }
\r
80 private static boolean useRundll32 = false;
\r
83 /*******************************************************************************
\r
85 ******************************************************************************/
\r
87 public static final String[] WDTPTN = {"日","月","火","水","木","金","土"};
\r
92 public static int getWday(String s) {
\r
93 if ( s == null || s.length() == 0 ) {
\r
97 String x = s.substring(0,1);
\r
98 for ( int i=0; i<WDTPTN.length; i++ ) {
\r
99 if ( WDTPTN[i].equals(x) ) {
\r
109 public static String getDateByMD(int m, int d, int wday, boolean addwstr) {
\r
110 return getDate(getCalendarByMD(m,d,wday),addwstr);
\r
116 public static GregorianCalendar getCalendarByMD(int m, int d, int wday) {
\r
117 GregorianCalendar c = new GregorianCalendar(
\r
118 Calendar.getInstance().get(Calendar.YEAR),
\r
123 if ( c.get(Calendar.DAY_OF_WEEK) == wday ) {
\r
128 c.add(Calendar.YEAR, 1);
\r
129 if ( c.get(Calendar.DAY_OF_WEEK) == wday ) {
\r
139 * 深夜帯(24:00~28:59)かどうか判定する
\r
141 public static boolean isLateNight(GregorianCalendar A) {
\r
142 return isLateNight(A.get(Calendar.HOUR_OF_DAY));
\r
146 * 深夜帯(24:00~28:59)かどうか判定する
\r
148 public static boolean isLateNight(String Ahh) {
\r
149 return ("00".compareTo(Ahh) <= 0 && "05".compareTo(Ahh) > 0);
\r
153 * 深夜帯(24:00~28:59)かどうか判定する
\r
155 public static boolean isLateNight(int Ahh) {
\r
156 return (Ahh >= 0 && Ahh < 5);
\r
160 * 開始・終了時刻から長さを算出する。引数の前後関係は意識しなくて良い。
\r
162 public static String getRecMin(GregorianCalendar ca, GregorianCalendar cz) {
\r
163 return String.valueOf(getRecMinVal(ca, cz));
\r
167 * 開始・終了時刻から長さを算出する。引数の前後関係は意識しなくて良い。
\r
169 public static String getRecMin(String start, String end) {
\r
170 return String.valueOf(getRecMinVal(start,end));
\r
173 public static String getRecMin(String ahhStr,String ammStr,String zhhStr,String zmmStr) {
\r
174 return String.valueOf(getRecMinVal(ahhStr,ammStr,zhhStr,zmmStr));
\r
178 * 開始・終了時刻から長さを算出する。引数の前後関係は意識しなくて良い。
\r
180 public static long getRecMinVal(GregorianCalendar ca, GregorianCalendar cz) {
\r
181 return getDiffDateTime(ca, cz)/60000L;
\r
185 * 開始・終了時刻から長さを算出する。引数の前後関係は意識しなくて良い。
\r
186 * @param start hh:mm
\r
189 public static int getRecMinVal(String start, String end) {
\r
190 Matcher ma = Pattern.compile("(\\d\\d):(\\d\\d)").matcher(start);
\r
191 Matcher mb = Pattern.compile("(\\d\\d):(\\d\\d)").matcher(end);
\r
192 if ( ! ma.find() || ! mb.find()) {
\r
195 return getRecMinVal(ma.group(1),ma.group(2),mb.group(1),mb.group(2));
\r
199 * 開始・終了時刻から長さを算出する。引数の前後関係は意識しなくて良い。
\r
201 public static int getRecMinVal(String ahhStr,String ammStr,String zhhStr,String zmmStr) {
\r
203 return getRecMinVal(Integer.valueOf(ahhStr), Integer.valueOf(ammStr), Integer.valueOf(zhhStr), Integer.valueOf(zmmStr));
\r
205 catch ( NumberFormatException e ) {
\r
206 System.err.println("[ERROR] at getRecMin(): "+ahhStr+","+ammStr+","+zhhStr+","+zmmStr);
\r
207 e.printStackTrace();
\r
213 * 開始・終了時刻から長さを算出する。引数の前後関係は意識しなくて良い。
\r
215 private static int getRecMinVal(int ahh, int amm, int zhh, int zmm) {
\r
216 int min = (zhh*60+zmm) - (ahh*60+amm);
\r
217 if (min < 0) min += 24*60;
\r
222 * @see #getCritDateTime(int)
\r
224 public static String getCritDateTime() {
\r
225 return getCritDateTime(0);
\r
228 * <P>ここより前は「前日」分であり過去情報であると判断するための基準日時を生成する。
\r
229 * <P>要するに、「当日」の "YYYY/MM/DD 05:00" (「当日」なので、日付は {@link #getDate529} の値)
\r
230 * @param n : n日先の基準日時か。当日の場合は0
\r
232 public static String getCritDateTime(int n) {
\r
233 return getDate529(n*86400,false)+" 05:00";
\r
237 * @param showpassed true:{@link #getCritDateTime()}と等価、false:{@link #getDateTime(int)}と等価
\r
240 public static String getCritDateTime(boolean showpassed) {
\r
242 return getCritDateTime(0);
\r
245 return getDateTime(0);
\r
251 * @see #getStartEndList(ArrayList, ArrayList, ReserveList)
\r
253 public static String getNextDate(ReserveList r) {
\r
255 ArrayList<String> starts = new ArrayList<String>();
\r
256 ArrayList<String> ends = new ArrayList<String>();
\r
257 CommonUtils.getStartEndList(starts, ends, r);
\r
258 if (starts.size() > 0) {
\r
259 GregorianCalendar c = getCalendar(starts.get(0));
\r
261 return(getDate(c));
\r
265 // エラーの場合は1970/01/01を返す
\r
266 return(getDate(new GregorianCalendar(1970,0,1)));
\r
271 * @see #getNextDate(ReserveList)
\r
273 public static void getStartEndList(ArrayList<String> starts, ArrayList<String> ends, ReserveList r) {
\r
275 int ptnid = r.getRec_pattern_id();
\r
277 //boolean isOverDay = (r.getAhh().compareTo(r.getZhh()) > 0); // 日付をまたいだ
\r
278 //boolean isLateNight = (adjLateNight == false && ( ptnid >= 7 && ptnid <= 10 ) && isLateNight(r.getAhh())); // 深夜帯(毎日&帯予約のみ利用)
\r
280 int len = Integer.valueOf(getRecMin(r.getAhh(), r.getAmm(), r.getZhh(), r.getZmm()));
\r
282 // 予約パターンによりけり対象となる日付は増えたり増えたり
\r
285 GregorianCalendar d = getCalendar(r.getRec_pattern()+" "+r.getAhh()+":"+r.getAmm());
\r
287 starts.add(getDateTime(d));
\r
288 d.add(Calendar.MINUTE,len);
\r
289 ends.add(getDateTime(d));
\r
295 GregorianCalendar cur = getCalendar(0);
\r
296 GregorianCalendar cri = getCalendar(getCritDateTime());
\r
299 GregorianCalendar cond;
\r
300 if ( displayPassedReserve ) {
\r
301 cond = (GregorianCalendar) cri.clone(); // 過去予約表示
\r
304 cond = (GregorianCalendar) cur.clone(); // 現在日時以上
\r
308 GregorianCalendar cz = (GregorianCalendar) cur.clone();
\r
309 cz.add(Calendar.DATE, dogDays);
\r
312 GregorianCalendar ca = (GregorianCalendar) cri.clone();
\r
313 if ( isLateNight(r.getAhh()) ) {
\r
314 ca.add(Calendar.DATE, 1);
\r
316 ca.set(Calendar.HOUR_OF_DAY, Integer.valueOf(r.getAhh()));
\r
317 ca.set(Calendar.MINUTE, Integer.valueOf(r.getAmm()));
\r
318 GregorianCalendar cb = (GregorianCalendar) ca.clone();
\r
319 cb.set(Calendar.HOUR_OF_DAY, Integer.valueOf(r.getZhh()));
\r
320 cb.set(Calendar.MINUTE, Integer.valueOf(r.getZmm()));
\r
321 if ( cb.compareTo(ca) < 0 ) {
\r
322 cb.add(Calendar.DATE, 1); // 終了日時より開始日時が大きいならば
\r
326 boolean islatenight = isLateNight(r.getAhh());
\r
328 while (ca.compareTo(cz) < 0)
\r
330 if ( cond.compareTo(cb) > 0 ) {
\r
332 ca.add(Calendar.DATE, 1);
\r
333 cb.add(Calendar.DATE, 1);
\r
337 boolean isReserved = false; // 過去の予約=false
\r
343 else if (9 >= ptnid && ptnid >= 7) {
\r
345 int wd = ca.get(Calendar.DAY_OF_WEEK);
\r
346 if ( islatenight ) {
\r
347 if ( adjLateNight ) {
\r
349 if ( Calendar.MONDAY <= wd && wd <= (r.getRec_pattern_id()-2) ) {
\r
355 if ( Calendar.TUESDAY <= wd && wd <= (r.getRec_pattern_id()-1) ) {
\r
358 else if ( ptnid == 9 && wd == Calendar.SUNDAY ) {
\r
365 if ( Calendar.MONDAY <= wd && wd <= (r.getRec_pattern_id()-2) ) {
\r
370 else if (ptnid < 7) {
\r
372 if ( ptnid == (ca.get(Calendar.DAY_OF_WEEK)-1) ) {
\r
378 GregorianCalendar ct = (GregorianCalendar) ca.clone();
\r
379 ct.add(Calendar.MINUTE,len);
\r
380 starts.add(getDateTime(ca));
\r
381 ends.add(getDateTime(ct));
\r
384 ca.add(Calendar.DATE, 1);
\r
385 cb.add(Calendar.DATE, 1);
\r
391 * <P>aとbの差をミリ秒で返す(正/負)
\r
392 * <P>秒に直すなら 1000、分に直すなら 60000で割る。
\r
393 * @see #getDiffDateTime
\r
395 public static long getCompareDateTime(String a, String b) {
\r
396 GregorianCalendar d = getCalendar(a);
\r
397 GregorianCalendar e = getCalendar(b);
\r
398 if ( d == null || e == null ) {
\r
401 return getCompareDateTime(d.getTimeInMillis(), e.getTimeInMillis());
\r
405 * <P>aとbの差をミリ秒で返す(正/負)
\r
406 * <P>秒に直すなら 1000、分に直すなら 60000で割る。
\r
407 * @see #getDiffDateTime
\r
409 public static long getCompareDateTime(GregorianCalendar a, GregorianCalendar b) {
\r
410 return getCompareDateTime(a.getTimeInMillis(), b.getTimeInMillis());
\r
413 private static long getCompareDateTime(long x, long y) {
\r
418 * <P>aとbの差をミリ秒で返す(絶対値)
\r
419 * <P>秒に直すなら 1000、分に直すなら 60000で割る。
\r
420 * @see #getCompareDateTime
\r
422 public static long getDiffDateTime(String a, String b) {
\r
423 GregorianCalendar d = getCalendar(a);
\r
424 GregorianCalendar e = getCalendar(b);
\r
425 if ( d == null || e == null ) {
\r
428 return getDiffDateTime(d.getTimeInMillis(), e.getTimeInMillis());
\r
433 * <P>秒に直すなら 1000、分に直すなら 60000で割る。
\r
435 public static long getDiffDateTime(GregorianCalendar a, GregorianCalendar b) {
\r
436 return getDiffDateTime(a.getTimeInMillis(), b.getTimeInMillis());
\r
439 private static long getDiffDateTime(long x, long y) {
\r
440 return ((x>y)?(x-y):(y-x));
\r
445 * 現在時刻+n秒のCalendarを返す
\r
447 public static GregorianCalendar getCalendar(int n) {
\r
448 GregorianCalendar c = new GregorianCalendar();
\r
449 //c.setTime(new Date());
\r
450 c.add(Calendar.SECOND, n);
\r
454 * 日付時刻文字列をCalendarに変換
\r
455 * @param date YYYY/MM/DD[(.)][ hh:mm[:ss]] or YYYY-MM-DD[Thh:mm[:ss]] or YYYYMMDD[hhmm[ss]]
\r
457 public static GregorianCalendar getCalendar(String date) {
\r
458 Matcher ma = Pattern.compile("^(\\d\\d\\d\\d)[/-](\\d{1,2})[/-](\\d{1,2})(\\(.\\))?([ T](\\d{1,2}):(\\d{1,2})(:\\d{1,2})?)?$").matcher(date);
\r
459 if ( ! ma.find()) {
\r
460 ma = Pattern.compile("^(\\d\\d\\d\\d)(\\d\\d)(\\d\\d)()?((\\d\\d)(\\d\\d)(\\d\\d)?)?$").matcher(date);
\r
461 if ( ! ma.find()) {
\r
466 GregorianCalendar c = null;
\r
467 if ( ma.group(5) == null ) {
\r
468 c = new GregorianCalendar(
\r
469 Integer.valueOf(ma.group(1)),
\r
470 Integer.valueOf(ma.group(2))-1,
\r
471 Integer.valueOf(ma.group(3)),
\r
477 c = new GregorianCalendar(
\r
478 Integer.valueOf(ma.group(1)),
\r
479 Integer.valueOf(ma.group(2))-1,
\r
480 Integer.valueOf(ma.group(3)),
\r
481 Integer.valueOf(ma.group(6)),
\r
482 Integer.valueOf(ma.group(7)),
\r
489 * 現在日時+n秒を日付時刻形式に変換。
\r
490 * @param n : 負の値を許可する
\r
491 * @return YYYY/MM/DD hh:mm
\r
493 public static String getDateTime(int n) {
\r
494 GregorianCalendar c = new GregorianCalendar();
\r
495 //c.setTime(new Date());
\r
496 c.add(Calendar.SECOND, n);
\r
497 return getDateTime(c);
\r
501 * 日時を日付時刻形式に変換。曜日文字がつかない。
\r
502 * @see #getDateTimeW(GregorianCalendar)
\r
503 * @see #getIsoDateTime(GregorianCalendar)
\r
504 * @see #getDateTimeYMD(GregorianCalendar)
\r
505 * @return YYYY/MM/DD hh:mm
\r
507 public static String getDateTime(GregorianCalendar c) {
\r
508 return new SimpleDateFormat("yyyy/MM/dd HH:mm").format(c.getTime());
\r
512 * 現在日時+n秒を日付時刻形式に変換。曜日文字がつく。
\r
513 * @param n : 負の値を許可する
\r
514 * @return YYYY/MM/DD hh:mm
\r
516 public static String getDateTimeW(int n) {
\r
517 GregorianCalendar c = new GregorianCalendar();
\r
518 //c.setTime(new Date());
\r
519 c.add(Calendar.SECOND, n);
\r
520 return getDateTimeW(c);
\r
524 * 日時を日付時刻形式に変換。曜日文字がつく。
\r
525 * @see #getDateTime(GregorianCalendar)
\r
526 * @return YYYY/MM/DD(WD) hh:mm
\r
528 public static String getDateTimeW(GregorianCalendar c) {
\r
529 return new SimpleDateFormat("yyyy/MM/dd('"+WDTPTN[c.get(Calendar.DAY_OF_WEEK)-1]+"') HH:mm").format(c.getTime());
\r
533 * 日時を日付時刻形式に変換。ISO形式。秒まで返却。
\r
534 * @see #getDateTime(GregorianCalendar)
\r
535 * @return YYYY-MM-DDThh:mm:ss
\r
537 public static String getIsoDateTime(GregorianCalendar c) {
\r
538 return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(c.getTime());
\r
542 * 現在日時+n秒を日付時刻形式に変換。
\r
543 * @see #getDateTime(GregorianCalendar)
\r
544 * @param n : 負の値を許可する
\r
545 * @return YYYYMMDDhhmmss
\r
547 public static String getDateTimeYMD(int n) {
\r
548 GregorianCalendar c = new GregorianCalendar();
\r
549 //c.setTime(new Date());
\r
550 if (n != 0) c.add(Calendar.SECOND, n);
\r
551 return getDateTimeYMD(c);
\r
555 * 日時を日付時刻形式に変換。YMD形式。秒まで返却。
\r
556 * @see #getDateTime(GregorianCalendar)
\r
557 * @return YYYYMMDDhhmmss
\r
559 public static String getDateTimeYMD(GregorianCalendar c) {
\r
560 return new SimpleDateFormat("yyyyMMddHHmmss").format(c.getTime());
\r
564 * 日時を日付時刻形式に変換。YMD形式。ミリ秒まで返却。
\r
565 * @see #getDateTime(GregorianCalendar)
\r
566 * @return YYYYMMDDhhmmssSSS
\r
568 public static String getDateTimeYMDx(GregorianCalendar c) {
\r
569 return new SimpleDateFormat("yyyyMMddHHmmssSSS").format(c.getTime());
\r
573 * <P>「当日」の日付文字列を返します。
\r
574 * <P>ただし、05時~29時を当日として判断するので、<B>24時~29時に実行した場合は前日の日付が返ります</B>。
\r
575 * @param n : 現在日時に対して n秒 加えた日時を返します。負の値も許可されます。
\r
576 * @param addwdstr : trueの場合、日付に曜日文字[これ->(日)]を加えます。
\r
577 * @return YYYY/MM/DD[(WD)] hh:mm:ss
\r
579 public static String getDate529(int n, boolean addwdstr) {
\r
580 GregorianCalendar c = getCalendar(0);
\r
581 c.add(Calendar.SECOND, n);
\r
582 return getDate529(c, addwdstr);
\r
585 * @see #getDate529(int, boolean)
\r
587 public static String getDate529(String s, boolean addwdstr) {
\r
588 GregorianCalendar c = getCalendar(s);
\r
589 return getDate529(c, addwdstr);
\r
592 * @see #getDate529(int, boolean)
\r
594 public static String getDate529(GregorianCalendar c, boolean addwdstr) {
\r
595 // 今日の範囲は05:00~04:59まで
\r
596 if ( isLateNight(c.get(Calendar.HOUR_OF_DAY)) ) {
\r
597 c.add(Calendar.DAY_OF_MONTH, -1);
\r
599 return getDate(c, addwdstr);
\r
604 * @return YYYY/MM/DD(WD)
\r
606 public static String getDate(GregorianCalendar c) {
\r
607 return getDate(c, true);
\r
612 * @param addwdstr : trueの場合、日付に曜日文字[これ->(日)]を加えます。
\r
613 * @return YYYY/MM/DD[(WD)]
\r
615 public static String getDate(GregorianCalendar c, boolean addwdstr) {
\r
617 return new SimpleDateFormat("yyyy/MM/dd('"+WDTPTN[c.get(Calendar.DAY_OF_WEEK)-1]+"')").format(c.getTime());
\r
620 return new SimpleDateFormat("yyyy/MM/dd").format(c.getTime());
\r
625 * <P>「当日」の日付文字列を返します。
\r
626 * <P>ただし、05時~29時を当日として判断するので、<B>24時~29時に実行した場合は前日の日付が返ります</B>。
\r
627 * @param n : 現在日時に対して n秒 加えた日時を返します。負の値も許可されます。
\r
630 public static String getDateYMD529(int n) {
\r
631 GregorianCalendar c = new GregorianCalendar();
\r
632 //c.setTime(new Date());
\r
633 c.add(Calendar.SECOND, n);
\r
635 // 今日の範囲は05:00~04:59まで
\r
636 if (c.get(Calendar.HOUR_OF_DAY) < 5) {
\r
637 c.add(Calendar.DAY_OF_MONTH, -1);
\r
640 return getDateYMD(c);
\r
645 * @param n : 負の値を許可する。
\r
648 public static String getDateYMD(int n) {
\r
649 GregorianCalendar ca = CommonUtils.getCalendar(n);
\r
650 return getDateYMD(ca);
\r
657 public static String getDateYMD(GregorianCalendar c) {
\r
658 return new SimpleDateFormat("yyyyMMdd").format(c.getTime());
\r
665 public static String getTime(int n) {
\r
666 return getTime(getCalendar(n));
\r
673 public static String getTime(GregorianCalendar c) {
\r
674 return getTime(c.get(Calendar.HOUR_OF_DAY),c.get(Calendar.MINUTE));
\r
679 * @see #getTimeHM(GregorianCalendar)
\r
682 public static String getTime(int hh, int mm) {
\r
683 return String.format("%02d:%02d",hh,mm);
\r
688 * @see #getTime(GregorianCalendar)
\r
691 public static String getTimeHM(int n) {
\r
692 return getTimeHM(getCalendar(n));
\r
697 * @see #getTime(GregorianCalendar)
\r
700 public static String getTimeHM(GregorianCalendar c) {
\r
701 return getTimeHM(c.get(Calendar.HOUR_OF_DAY),c.get(Calendar.MINUTE));
\r
706 * @see #getTime(GregorianCalendar)
\r
709 public static String getTimeHM(int hh, int mm) {
\r
710 return String.format("%02d%02d",hh,mm);
\r
714 * 時間帯の重複があるかどうかを判定します。
\r
715 * @param adjnotrep : falseの場合、終了時刻と開始時刻が重なるものを重複として扱います。
\r
717 public static boolean isOverlap(String start1, String end1, String start2, String end2, boolean adjnotrep) {
\r
719 return( ! (end1.compareTo(start2) <= 0 || end2.compareTo(start1) <= 0));
\r
722 return( ! (end1.compareTo(start2) < 0 || end2.compareTo(start1) < 0));
\r
727 /*******************************************************************************
\r
729 ******************************************************************************/
\r
733 * @param s : 色化する文字列 "#xxxxxx;" (R、G、B 各16進2ケタ)
\r
734 * @return {@link Color}
\r
735 * @see #color2str(Color c)
\r
737 public static Color str2color(String s) {
\r
739 Matcher ma = Pattern.compile("#(..)(..)(..)").matcher(s);
\r
741 int r = Integer.decode("0x"+ma.group(1));
\r
742 int g = Integer.decode("0x"+ma.group(2));
\r
743 int b = Integer.decode("0x"+ma.group(3));
\r
744 return(new Color(r,g,b));
\r
746 return new Color(0,0,0);
\r
748 catch (NumberFormatException e) {
\r
749 e.printStackTrace();
\r
756 * @param c : 文字列化する色({@link Color})
\r
757 * @return "#xxxxxx;" (R、G、B 各16進2ケタ)
\r
758 * @see #str2color(String)
\r
760 public static String color2str(Color c) {
\r
761 return String.format("#%02x%02x%02x", c.getRed(), c.getGreen(), c.getBlue());
\r
765 /*******************************************************************************
\r
767 ******************************************************************************/
\r
769 public static String joinPath(String... path) {
\r
770 return joinStr(File.separator, path);
\r
773 public static String joinStr(String s, ArrayList<String> a) {
\r
774 return joinStr(s,a.toArray(new String[0]));
\r
777 public static String joinStr(String s, String... a) {
\r
778 if (a.length <= 0) {
\r
781 StringBuffer sb = new StringBuffer();
\r
782 for (int i=0; i<a.length-1; i++) {
\r
786 sb.append(a[a.length-1]);
\r
787 return(sb.toString());
\r
791 * 文字数ではなく、バイト数でのsubstringを行います。
\r
796 public static String substringrb(String s, int length) {
\r
797 StringBuilder sb = new StringBuilder();
\r
799 for ( Character c : s.toCharArray() ) {
\r
800 len += (c<256)?(1):(2);
\r
801 if (len > length) {
\r
804 sb.append(c.toString());
\r
806 return(sb.toString());
\r
809 private static final char[] NGCharList = "\\/:*?\"<>|".toCharArray();
\r
812 * ファイル名に使用できない文字の一覧を返します。
\r
814 public static String getNGCharList() {
\r
815 return new String(NGCharList);
\r
819 * ファイル名に使用できない文字が含まれているかどうか判定します。
\r
821 public static boolean isNGChar(String s) {
\r
822 for (int i=0; i<NGCharList.length; i++) {
\r
823 if (s.indexOf(NGCharList[i]) >= 0) {
\r
831 * ファイル名に使用できない文字をHTMLエスケープ(&#ddd;)します。
\r
832 * @see #unEscape(String)
\r
834 public static String escapeFilename(String src) {
\r
835 for (int i=0; i<NGCharList.length; i++) {
\r
836 src = src.replaceAll(String.format("\\%s",String.valueOf(NGCharList[i])), String.format("&#%03d;", (int)NGCharList[i]));
\r
842 * HTMLエスケープをデコードします。
\r
844 public static String unEscape(String src) {
\r
845 String dst = src.replaceAll(""", "\"");
\r
846 dst = dst.replaceAll("<", "<");
\r
847 dst = dst.replaceAll(">", ">");
\r
848 dst = dst.replaceAll("&", "&");
\r
849 dst = dst.replaceAll(" ", " ");
\r
850 dst = dst.replaceAll("〜", "~");
\r
851 dst = dst.replaceAll("−", "-");
\r
852 HashMap<String, String> ek = new HashMap<String, String>();
\r
853 Matcher ma = Pattern.compile("(&#(\\d+);)").matcher(src);
\r
854 while (ma.find()) {
\r
855 ek.put(ma.group(1), Character.valueOf((char)(int)Integer.valueOf(ma.group(2))).toString());
\r
857 for (Entry<String, String> kv : ek.entrySet()) {
\r
858 dst = dst.replaceAll(kv.getKey(), kv.getValue());
\r
864 * Unicodeエスケープをデコードします。
\r
866 public static String unUniEscape(String src) {
\r
867 Matcher ma = Pattern.compile("\\\\u[0-9a-f]{4}").matcher(src);
\r
868 StringBuffer sb = new StringBuffer(src.length());
\r
869 while (ma.find()) {
\r
870 char[] chars = ma.group().substring(2, 6).toCharArray();
\r
872 for (char c : chars) {
\r
874 if ('a' <= c && c <= 'f') {
\r
875 hex += c - 'a' + 10;
\r
881 ma.appendReplacement(sb, ""+(char)hex);
\r
884 return sb.toString();
\r
889 * 文字列中の全角数字を半角数字に置き換えます
\r
891 public static String toHANUM(String numTmp) {
\r
892 if (numTmp == null) return null;
\r
894 StringBuilder sb = new StringBuilder();
\r
895 for ( int i=0; i<numTmp.length(); i++ ) {
\r
896 char c = numTmp.charAt(i);
\r
897 if ( '0' <= c && c <= '9' ) {
\r
898 c = (char)(c - '0' + '0' );
\r
902 return sb.toString();
\r
905 public static String toHANALNUM(String alnumTmp) {
\r
906 if (alnumTmp == null) return null;
\r
908 StringBuilder sb = new StringBuilder();
\r
909 for ( int i=0; i<alnumTmp.length(); i++ ) {
\r
910 char c = alnumTmp.charAt(i);
\r
911 if ( 'a' <= c && c <= 'z' ) {
\r
912 c = (char)(c - 'a' + 'a' );
\r
914 else if ( 'A' <= c && c <= 'Z' ) {
\r
915 c = (char)(c - 'A' + 'A' );
\r
917 else if ( '0' <= c && c <= '9' ) {
\r
918 c = (char)(c - '0' + '0' );
\r
920 else if ( c == '(' ) {
\r
923 else if ( c == ')' ) {
\r
926 else if ( c == '-' ) {
\r
929 else if ( c == ' ' ) {
\r
934 return sb.toString();
\r
937 /*******************************************************************************
\r
939 ******************************************************************************/
\r
941 /*******************************************************************************
\r
943 ******************************************************************************/
\r
946 * デバッグ用にスタックトレースをとりたいなー
\r
948 public static void printStackTrace() {
\r
949 if ( ! debug) return;
\r
951 new Throwable().printStackTrace();
\r
954 /*******************************************************************************
\r
956 ******************************************************************************/
\r
958 // なぜJavaなのに機種別のコードをかかなければならないのか…
\r
959 public static boolean isMac() { return ismac; }
\r
960 public static boolean isLinux() { return islinux; }
\r
961 public static boolean isWindows() { return iswindows; }
\r
962 public static boolean isWindowsXP() { return iswindowsxp; }
\r
964 private static final boolean ismac = ((String)System.getProperty("os.name")).toLowerCase().replaceAll(" ", "").startsWith("macosx");
\r
965 private static final boolean islinux = ((String)System.getProperty("os.name")).toLowerCase().replaceAll(" ", "").startsWith("linux");
\r
966 private static final boolean iswindows = ((String)System.getProperty("os.name")).toLowerCase().replaceAll(" ", "").startsWith("windows");
\r
967 private static final boolean iswindowsxp= ((String)System.getProperty("os.name")).toLowerCase().replaceAll(" ", "").startsWith("windowsxp");
\r
970 public static void milSleep(int i) {
\r
974 catch (InterruptedException e) {
\r
975 System.err.println("[スリープ] なんかあったのか");
\r
976 e.printStackTrace();
\r
982 * @see #getCommandResult()
\r
983 * @param run : コマンドの指定
\r
984 * @return -1 : 失敗、-1以外 : コマンドのexit値
\r
986 public static int executeCommand(String run) {
\r
988 commandResult = null;
\r
990 ArrayList<String> list = new ArrayList<String>();
\r
991 Matcher ma = Pattern.compile("((\"([^\"]*?)\"|([^\"]+?))(\\s+|$))").matcher(run);
\r
992 while (ma.find()) {
\r
993 if (ma.group(3) != null) {
\r
994 list.add(ma.group(3));
\r
997 list.add(ma.group(4));
\r
1000 if ( list.size() == 0 ) {
\r
1001 System.err.println("[外部コマンド] 実行できません: "+run);
\r
1005 ProcessBuilder pb = null;
\r
1008 InputStream is = null;
\r
1009 InputStreamReader isr = null;
\r
1010 BufferedReader br = null;
\r
1013 pb = new ProcessBuilder(list);
\r
1014 pb.redirectErrorStream(true);
\r
1017 p.getOutputStream().close(); // 入力はしない
\r
1019 String encoding = (isWindows())?("MS932"):("UTF-8");
\r
1021 StringBuilder sb = new StringBuilder();
\r
1022 is = p.getInputStream();
\r
1023 isr = new InputStreamReader(is,encoding);
\r
1024 br = new BufferedReader(isr);
\r
1026 while ((s=br.readLine()) != null) {
\r
1030 commandResult = sb.toString();
\r
1032 System.out.println("--- 外部コマンドを実行します ---");
\r
1033 System.out.println(commandResult);
\r
1034 System.out.println("--- 外部コマンドを実行しました ---");
\r
1036 p.waitFor(); // is.read()で判定できるので不要
\r
1038 int retval = p.exitValue();
\r
1042 catch ( IOException e ) {
\r
1043 System.err.println("[外部コマンド] 失敗しました: "+run);
\r
1044 e.printStackTrace();
\r
1046 catch ( InterruptedException e ) {
\r
1047 System.err.println("[外部コマンド] 失敗しました: "+run);
\r
1048 e.printStackTrace();
\r
1055 if ( p != null ) {
\r
1056 closing(p.getInputStream());
\r
1057 closing(p.getErrorStream());
\r
1066 public static String getCommandResult() { return commandResult; }
\r
1068 private static String commandResult;
\r
1071 * 登録されたアプリケーションでファイルを開く
\r
1073 public static String openFile(String file) {
\r
1074 String errmsg = null;
\r
1076 if ( useRundll32 && isWindows() ) {
\r
1077 Runtime runtime = Runtime.getRuntime();
\r
1078 runtime.exec("rundll32 url.dll,FileProtocolHandler "+new File(file).getAbsolutePath());
\r
1081 Desktop desktop = Desktop.getDesktop();
\r
1082 desktop.open(new File(file));
\r
1085 catch (UnsupportedOperationException e) {
\r
1086 System.err.println("[アプリケーションでファイルを開く] 失敗しました: "+file);
\r
1087 e.printStackTrace();
\r
1088 errmsg = e.toString();
\r
1090 catch (IOException e) {
\r
1091 System.err.println("[アプリケーションでファイルを開く] 失敗しました: "+file);
\r
1092 e.printStackTrace();
\r
1093 errmsg = e.toString();
\r
1099 /*******************************************************************************
\r
1101 ******************************************************************************/
\r
1104 public static boolean isFileAvailable(File f, int days) {
\r
1106 if ( ! f.exists() ) {
\r
1111 long lm = f.lastModified();
\r
1112 GregorianCalendar cal = new GregorianCalendar();
\r
1113 cal.setTimeInMillis(lm);
\r
1114 if ( getCompareDateTime(cal, getCalendar(-days*86400)) < 0 ) {
\r
1122 public static boolean rmdir(File f) {
\r
1123 if( ! f.exists()) {
\r
1128 return f.delete();
\r
1130 else if (f.isDirectory()) {
\r
1131 File[] files = f.listFiles();
\r
1132 for (File file : files){
\r
1133 if ( ! rmdir(file)) {
\r
1137 return f.delete();
\r
1140 return false; // ここには来ないはず
\r
1144 public static boolean saveCnt(int cnt, String filename) {
\r
1145 if ( ! write2file(filename, String.valueOf(cnt)) ) {
\r
1146 System.out.println("[カウンタファイル] 書き込めませんでした: "+filename);
\r
1151 public static int loadCnt(String filename) {
\r
1152 if ( ! new File(filename).exists() ) {
\r
1157 String str = read4file(filename, true);
\r
1158 if ( str != null ) {
\r
1159 return Integer.valueOf(str);
\r
1162 catch ( NumberFormatException e ) {
\r
1163 System.err.println("[カウンタファイル] 内容が不正です: "+filename);
\r
1166 System.err.println("[カウンタファイル] 読み込めませんでした: "+filename);
\r
1175 public static boolean getLock() {
\r
1176 FileOutputStream fos = null;
\r
1177 FileChannel fc = null;
\r
1179 fos = new FileOutputStream(new File("_lock_"));
\r
1180 fc = fos.getChannel();
\r
1181 lock = fc.tryLock();
\r
1182 if ( lock == null ) {
\r
1183 System.err.println("[多重起動禁止] ロックされています.");
\r
1190 catch (FileNotFoundException e) {
\r
1191 System.err.println("[多重起動禁止] ロックの取得に失敗しました.");
\r
1192 e.printStackTrace();
\r
1194 catch (IOException e) {
\r
1195 System.err.println("[多重起動禁止] ロックの取得に失敗しました.");
\r
1196 e.printStackTrace();
\r
1208 public static void getUnlock() {
\r
1210 if ( lock != null ) {
\r
1213 } catch (IOException e) {
\r
1214 System.err.println("[多重起動禁止] ロックの解放に失敗しました.");
\r
1215 e.printStackTrace();
\r
1219 private static FileLock lock = null;
\r
1222 * テキストをファイルに書き出す(エンコードはデフォルト)
\r
1224 public static boolean write2file(String fname, String dat) {
\r
1225 return write2file(fname, dat, null);
\r
1229 * テキストをファイルに書き出す(エンコードは指定による)
\r
1231 public static boolean write2file(String fname, String dat, String encoding) {
\r
1232 if ( fname.matches(".*\\.zip$") ) {
\r
1233 return _write2zip(fname, dat, encoding);
\r
1236 return _write2file(fname, dat, encoding);
\r
1239 private static boolean _write2zip(String fname, String dat, String encoding) {
\r
1241 FileOutputStream os = null;
\r
1242 BufferedOutputStream bos = null;
\r
1243 ZipOutputStream zos = null;
\r
1246 os = new FileOutputStream(fname+".tmp");
\r
1247 bos = new BufferedOutputStream(os);
\r
1248 zos = new ZipOutputStream(bos);
\r
1250 byte[] buf = null;
\r
1251 if ( encoding == null ) {
\r
1253 buf = dat.getBytes();
\r
1257 buf = dat.getBytes(encoding);
\r
1260 ZipEntry ze = new ZipEntry(ZIPENTRY);
\r
1261 ze.setSize(buf.length);
\r
1263 zos.putNextEntry(ze);
\r
1266 // 処理が続くので閉じないとアカン!
\r
1268 zos.close(); zos = null;
\r
1269 if (bos!=null) { bos.close(); bos = null; }
\r
1270 if (os!=null) { os.close(); os = null; }
\r
1273 File o = new File(fname);
\r
1274 if ( o.exists() && ! o.delete() ) {
\r
1275 System.err.println("削除できないよ: "+fname);
\r
1277 File n = new File(fname+".tmp");
\r
1278 if ( ! n.renameTo(o) ) {
\r
1279 System.err.println("リネームできないよ: "+fname);
\r
1282 catch (Exception e) {
\r
1284 System.out.println("書けないよ: "+e.toString());
\r
1295 private static boolean _write2file(String fname, String dat, String encoding) {
\r
1298 BufferedWriter bw = null;
\r
1299 FileOutputStream os = null;
\r
1302 if ( encoding == null ) {
\r
1304 wr = new FileWriter(fname+".tmp");
\r
1308 os = new FileOutputStream(new File(fname+".tmp"));
\r
1309 wr = new OutputStreamWriter(os, encoding);
\r
1311 bw = new BufferedWriter(wr);
\r
1314 // 処理が続くので閉じないとアカン!
\r
1315 bw.close(); bw = null;
\r
1316 wr.close(); wr = null;
\r
1317 if (os!=null) { os.close(); os = null; }
\r
1320 File o = new File(fname);
\r
1321 if ( o.exists() && ! o.delete() ) {
\r
1322 System.err.println("削除できないよ: "+fname);
\r
1324 File n = new File(fname+".tmp");
\r
1325 if ( ! n.renameTo(o) ) {
\r
1326 System.err.println("リネームできないよ: "+fname);
\r
1329 catch (Exception e) {
\r
1331 System.out.println("書けないよ: "+e.toString());
\r
1343 private static final String ZIPENTRY = "compressed.dat";
\r
1346 * テキストをファイルを読み出す(エンコードはデフォルト)
\r
1348 public static String read4file(String fname, boolean nocr) {
\r
1349 return read4file(fname, nocr, null);
\r
1353 * テキストをファイルを読み出す(エンコードは指定による)
\r
1355 public static String read4file(String fname, boolean nocr, String encoding) {
\r
1356 if ( fname.matches(".*\\.zip$") ) {
\r
1357 return _read4zip(fname, nocr, null);
\r
1360 return _read4file(fname, nocr, null);
\r
1363 private static String _read4zip(String fname, boolean nocr, String encoding) {
\r
1364 String response = null;
\r
1366 ZipFile zf = null;
\r
1368 InputStream is = null;
\r
1369 BufferedReader br = null;
\r
1372 zf = new ZipFile(fname);
\r
1373 ZipEntry ze = zf.getEntry(ZIPENTRY);
\r
1374 if ( ze == null ) {
\r
1375 System.out.println("ZIPファイルがおかしい");
\r
1379 is = zf.getInputStream(ze);
\r
1382 if ( encoding == null ) {
\r
1384 rd = new InputStreamReader(is);
\r
1388 rd = new InputStreamReader(is, encoding);
\r
1390 br = new BufferedReader(rd);
\r
1393 StringBuilder sb = new StringBuilder();
\r
1394 while ((str = br.readLine()) != null) {
\r
1396 if ( ! nocr ) sb.append("\n");
\r
1399 response = sb.toString();
\r
1401 catch (Exception e) {
\r
1403 System.out.println("読めないよ: "+e.toString());
\r
1415 private static String _read4file(String fname, boolean nocr, String encoding) {
\r
1416 String response = null;
\r
1419 BufferedReader br = null;
\r
1420 FileInputStream is = null;
\r
1423 if ( encoding == null ) {
\r
1425 rd = new FileReader(fname);
\r
1429 is = new FileInputStream(new File(fname));
\r
1430 rd = new InputStreamReader(is, encoding);
\r
1432 br = new BufferedReader(rd);
\r
1435 StringBuilder sb = new StringBuilder();
\r
1436 while ((str = br.readLine()) != null) {
\r
1438 if ( ! nocr ) sb.append("\n");
\r
1441 response = sb.toString();
\r
1443 catch (Exception e) {
\r
1445 System.out.println("読めないよ: "+e.toString());
\r
1458 * XMLEncoderでシリアライズしてファイルに出力する
\r
1460 public static boolean writeXML(String fname, Object obj) {
\r
1461 boolean done = true;
\r
1463 FileOutputStream fos = null;
\r
1464 BufferedOutputStream bos = null;
\r
1465 XMLEncoder enc = null;
\r
1467 fos = new FileOutputStream(fname+".tmp");
\r
1468 bos = new BufferedOutputStream(fos);
\r
1469 enc = new XMLEncoder(bos);
\r
1470 enc.writeObject(obj);
\r
1472 // 処理が続くので閉じないとアカン!
\r
1473 enc.close(); enc = null;
\r
1474 bos.close(); bos = null;
\r
1475 fos.close(); fos = null;
\r
1478 File o = new File(fname);
\r
1479 if ( o.exists() && ! o.delete() ) {
\r
1480 System.err.println("削除できないよ: "+fname);
\r
1482 File n = new File(fname+".tmp");
\r
1483 if ( ! n.renameTo(o) ) {
\r
1484 System.err.println("リネームできないよ: "+fname);
\r
1487 catch (Exception e) {
\r
1490 System.err.println(e.toString());
\r
1502 * XMLDecorderでシリアライズしたファイルを読みだす(オブジェクトを返す場合)
\r
1504 public static Object readXML(String fname) {
\r
1506 XMLDecoder dec = null;
\r
1507 FileInputStream fis = null;
\r
1508 BufferedInputStream bis = null;
\r
1510 fis = new FileInputStream(fname);
\r
1511 bis = new BufferedInputStream(fis);
\r
1512 dec = new XMLDecoder(bis);
\r
1513 return dec.readObject();
\r
1515 catch (Exception e) {
\r
1517 System.err.println(e.toString());
\r
1529 * XMLDecorderでシリアライズしたファイルを読みだす(既存のオブジェクトに値を入れて返す場合)
\r
1531 public static boolean readXML(String fname, Object obj) {
\r
1533 Object tmp = readXML(fname);
\r
1534 if ( tmp == null ) {
\r
1538 return FieldUtils.deepCopy(obj, tmp);
\r
1542 * finallyブロックで書き間違えそうなので
\r
1544 public static void closing(Reader r) {
\r
1545 if ( r != null ) try { r.close(); } catch (Exception e) {}
\r
1547 public static void closing(InputStream r) {
\r
1548 if ( r != null ) try { r.close(); } catch (Exception e) {}
\r
1550 public static void closing(ZipFile r) {
\r
1551 if ( r != null ) try { r.close(); } catch (Exception e) {}
\r
1553 public static void closing(XMLDecoder r) {
\r
1554 if ( r != null ) r.close();
\r
1557 public static void closing(Writer w) {
\r
1558 if ( w != null ) try { w.close(); } catch (Exception e) {}
\r
1560 public static void closing(OutputStream w) {
\r
1561 if ( w != null ) try { w.close(); } catch (Exception e) {}
\r
1563 public static void closing(XMLEncoder w) {
\r
1564 if ( w != null ) w.close();
\r
1567 public static void closing(FileChannel fc) {
\r
1568 if ( fc != null ) try { fc.close(); } catch (Exception e) {}
\r
1571 public static void closing(Socket sock) {
\r
1572 if ( sock != null ) try { sock.close(); } catch (Exception e) {}
\r
1574 public static void closing(HttpURLConnection ucon) {
\r
1575 if ( ucon != null ) ucon.disconnect();
\r