OSDN Git Service

スカパー変更対応ほか
[tainavi/TinyBannavi.git] / TinyBannavi / src / tainavi / CommonUtils.java
1 \r
2 package tainavi;\r
3 \r
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
40 \r
41 /**\r
42  * <P>頻繁に使用する雑多なメソッドをstaticで提供します。\r
43  * <P>パッケージを小分けにしておけばよかった…\r
44  */\r
45 public class CommonUtils {\r
46 \r
47         /*******************************************************************************\r
48          * CommonUtilsの動作設定\r
49          ******************************************************************************/\r
50 \r
51         /**\r
52          * デバッグログ出力するかどうか\r
53          */\r
54         public static void setDebug(boolean b) { debug = b; }\r
55         private static boolean debug = false;\r
56         \r
57         /**\r
58          *  深夜の帯予約補正に対応するかどうか\r
59          */\r
60         public static void setAdjLateNight(boolean b) { adjLateNight = b; }\r
61         private static boolean adjLateNight = false;\r
62         \r
63         /**\r
64          * Web番組表の8日分取得に対応するかどうか\r
65          */\r
66         public static void setExpandTo8(boolean b) { dogDays = ((b)?(8):(7)); }\r
67         private static int dogDays = 7;\r
68         \r
69         /**\r
70          * 過去予約の表示に対応するかどうか\r
71          */\r
72         public static void setDisplayPassedReserve(boolean b) { displayPassedReserve = b; }\r
73         private static boolean displayPassedReserve = false;\r
74         \r
75         /**\r
76          * Windows環境下で、アプリケーションに関連付けられたファイルを開くのにrundll32.exeを利用するかどうか\r
77          */\r
78         public static void setUseRundll32(boolean b) { useRundll32 = b; }\r
79         private static boolean useRundll32 = false;\r
80         \r
81         \r
82         /*******************************************************************************\r
83          * 日付時刻関連\r
84          ******************************************************************************/\r
85         \r
86         public static final String[] WDTPTN = {"日","月","火","水","木","金","土"};\r
87         \r
88         /**\r
89          * 曜日→wday\r
90          */\r
91         public static int getWday(String s) {\r
92                 if ( s == null || s.length() == 0 ) {\r
93                         return 0;\r
94                 }\r
95                 \r
96                 String x = s.substring(0,1);\r
97                 for ( int i=0; i<WDTPTN.length; i++ ) {\r
98                         if ( WDTPTN[i].equals(x) ) {\r
99                                 return i+1;\r
100                         }\r
101                 }\r
102                 return 0;\r
103         }\r
104         \r
105         /**\r
106          * 月日に年を補完\r
107          */\r
108         public static String getDateByMD(int m, int d, int wday, boolean addwstr) {\r
109                 return getDate(getCalendarByMD(m,d,wday),addwstr);\r
110         }\r
111         \r
112         /**\r
113          * 月日に年を補完\r
114          */\r
115         public static GregorianCalendar getCalendarByMD(int m, int d, int wday) {\r
116                 GregorianCalendar c = new GregorianCalendar(\r
117                                 Calendar.getInstance().get(Calendar.YEAR),\r
118                                 m-1,\r
119                                 d\r
120                                 );\r
121                 \r
122                 if ( c.get(Calendar.DAY_OF_WEEK) == wday ) {\r
123                         // 当年\r
124                         return c;\r
125                 }\r
126                 \r
127                 c.add(Calendar.YEAR, 1);\r
128                 if ( c.get(Calendar.DAY_OF_WEEK) == wday ) {\r
129                         // 翌年\r
130                         return c;\r
131                 }\r
132                 \r
133                 return null;\r
134         }\r
135 \r
136         \r
137         /**\r
138          * 深夜帯(24:00~28:59)かどうか判定する\r
139          */\r
140         public static boolean isLateNight(GregorianCalendar A) {\r
141                 return isLateNight(A.get(Calendar.HOUR_OF_DAY));\r
142         }\r
143         \r
144         /**\r
145          * 深夜帯(24:00~28:59)かどうか判定する\r
146          */\r
147         public static boolean isLateNight(String Ahh) {\r
148                 return ("00".compareTo(Ahh) <= 0 && "05".compareTo(Ahh) > 0);\r
149         }\r
150         \r
151         /**\r
152          * 深夜帯(24:00~28:59)かどうか判定する\r
153          */\r
154         public static boolean isLateNight(int Ahh) {\r
155                 return (Ahh >= 0 && Ahh < 5);\r
156         }\r
157         \r
158         /**\r
159          *  開始・終了時刻から長さを算出する。引数の前後関係は意識しなくて良い。\r
160          */\r
161         public static String getRecMin(GregorianCalendar ca, GregorianCalendar cz) {\r
162                 return String.valueOf(getRecMinVal(ca, cz));\r
163         }\r
164         \r
165         /**\r
166          *  開始・終了時刻から長さを算出する。引数の前後関係は意識しなくて良い。\r
167          */\r
168         public static String getRecMin(String start, String end) {\r
169                 return String.valueOf(getRecMinVal(start,end));\r
170         }\r
171 \r
172         public static String getRecMin(String ahhStr,String ammStr,String zhhStr,String zmmStr) {\r
173                 return String.valueOf(getRecMinVal(ahhStr,ammStr,zhhStr,zmmStr));\r
174         }\r
175 \r
176         /**\r
177          *  開始・終了時刻から長さを算出する。引数の前後関係は意識しなくて良い。\r
178          */\r
179         public static long getRecMinVal(GregorianCalendar ca, GregorianCalendar cz)     {\r
180                 return getDiffDateTime(ca, cz)/60000L;\r
181         }\r
182         \r
183         /**\r
184          * 開始・終了時刻から長さを算出する。引数の前後関係は意識しなくて良い。\r
185          * @param start hh:mm\r
186          * @param end hh:mm\r
187          */\r
188         public static int getRecMinVal(String start, String end) {\r
189                 Matcher ma = Pattern.compile("(\\d\\d):(\\d\\d)").matcher(start);\r
190                 Matcher mb = Pattern.compile("(\\d\\d):(\\d\\d)").matcher(end);\r
191                 if ( ! ma.find() || ! mb.find()) {\r
192                         return 0;\r
193                 }\r
194                 return getRecMinVal(ma.group(1),ma.group(2),mb.group(1),mb.group(2));\r
195         }\r
196         \r
197         /**\r
198          *  開始・終了時刻から長さを算出する。引数の前後関係は意識しなくて良い。\r
199          */\r
200         public static int getRecMinVal(String ahhStr,String ammStr,String zhhStr,String zmmStr) {\r
201                 try {\r
202                         return getRecMinVal(Integer.valueOf(ahhStr), Integer.valueOf(ammStr), Integer.valueOf(zhhStr), Integer.valueOf(zmmStr));\r
203                 }\r
204                 catch ( NumberFormatException e ) {\r
205                         System.err.println("[ERROR] at getRecMin(): "+ahhStr+","+ammStr+","+zhhStr+","+zmmStr);\r
206                         e.printStackTrace();\r
207                 }\r
208                 return 0;\r
209         }\r
210         \r
211         /**\r
212          *  開始・終了時刻から長さを算出する。引数の前後関係は意識しなくて良い。\r
213          */\r
214         public static int getRecMinVal(int ahh, int amm, int zhh, int zmm) {\r
215                 int min = (zhh*60+zmm) - (ahh*60+amm);\r
216                 if (min < 0) min += 24*60;\r
217                 return min;\r
218         }\r
219         \r
220         /**\r
221          *  1440分中の何分目か返す\r
222          */\r
223         public static int getMinOfDate(String ahh, String amm) {\r
224                 try {\r
225                         return getMinOfDate(Integer.valueOf(ahh),Integer.valueOf(amm));\r
226                 }\r
227                 catch (NumberFormatException e) {\r
228                         return -1;\r
229                 }\r
230         }\r
231         \r
232         /**\r
233          *  1440分中の何分目か返す\r
234          */\r
235         public static int getMinOfDate(int ahh, int amm) {\r
236                 return ahh*60+amm;\r
237         }\r
238         \r
239         /**\r
240          * @see #getCritDateTime(int)\r
241          */\r
242         public static String getCritDateTime() {\r
243                 return getCritDateTime(0);\r
244         }\r
245         /**\r
246          * <P>ここより前は「前日」分であり過去情報であると判断するための基準日時を生成する。\r
247          * <P>要するに、「当日」の "YYYY/MM/DD 05:00" (「当日」なので、日付は {@link #getDate529} の値)\r
248          * @param n : n日先の基準日時か。当日の場合は0 \r
249          */\r
250         public static String getCritDateTime(int n) {\r
251                 return getDate529(n*86400,false)+" 05:00";\r
252         }\r
253         /**\r
254          * \r
255          * @param showpassed true:{@link #getCritDateTime()}と等価、false:{@link #getDateTime(int)}と等価\r
256          * @return\r
257          */\r
258         public static String getCritDateTime(boolean showpassed) {\r
259                 if (showpassed) {\r
260                         return getCritDateTime(0);\r
261                 }\r
262                 else {\r
263                         return getDateTime(0);\r
264                 }\r
265         }\r
266         /**\r
267          * \r
268          */\r
269         public static GregorianCalendar getCritCalendar(String date) {\r
270                 GregorianCalendar ca = getCalendar(date);\r
271                 int hh = ca.get(Calendar.HOUR_OF_DAY);\r
272                 int mm = ca.get(Calendar.MINUTE);\r
273                 int ss = ca.get(Calendar.SECOND);\r
274                 ca.add(Calendar.HOUR_OF_DAY,-hh+5);\r
275                 ca.add(Calendar.MINUTE,-mm);\r
276                 ca.add(Calendar.SECOND,-ss);\r
277                 return ca;\r
278         }\r
279         \r
280         /**\r
281          * 次回実行予定日を取得する\r
282          * @see #getStartEndList(ArrayList, ArrayList, ReserveList)\r
283          */\r
284         public static String getNextDate(ReserveList r) {\r
285                 \r
286                 ArrayList<String> starts = new ArrayList<String>();\r
287                 ArrayList<String> ends = new ArrayList<String>();\r
288                 CommonUtils.getStartEndList(starts, ends, r);\r
289                 if (starts.size() > 0) {\r
290                         GregorianCalendar c = getCalendar(starts.get(0));\r
291                         if (c != null) {\r
292                                 return(getDate(c));\r
293                         }\r
294                 }\r
295                 \r
296                 // エラーの場合は1970/01/01を返す\r
297                 return(getDate(new GregorianCalendar(1970,0,1)));\r
298         }\r
299         \r
300         /**\r
301          * 開始・終了日時のリストを作成する\r
302          * @see #getNextDate(ReserveList)\r
303          */\r
304         public static void getStartEndList(ArrayList<String> starts, ArrayList<String> ends, ReserveList r) {\r
305                 \r
306                 int ptnid = r.getRec_pattern_id();\r
307                 \r
308                 //boolean isOverDay = (r.getAhh().compareTo(r.getZhh()) > 0);           // 日付をまたいだ\r
309                 //boolean isLateNight = (adjLateNight == false && ( ptnid >= 7 && ptnid <= 10 ) && isLateNight(r.getAhh()));    // 深夜帯(毎日&帯予約のみ利用)\r
310                 \r
311                 int len = Integer.valueOf(getRecMin(r.getAhh(), r.getAmm(), r.getZhh(), r.getZmm()));\r
312                 \r
313                 // 予約パターンによりけり対象となる日付は増えたり増えたり\r
314                 if (ptnid == 11) {\r
315                         // 単日\r
316                         GregorianCalendar d = getCalendar(r.getRec_pattern()+" "+r.getAhh()+":"+r.getAmm());\r
317                         if (d != null) {\r
318                                 starts.add(getDateTime(d));\r
319                                 d.add(Calendar.MINUTE,len);\r
320                                 ends.add(getDateTime(d));\r
321                         }\r
322                 }\r
323                 else {\r
324                         \r
325                         // 基準日時\r
326                         GregorianCalendar cur = getCalendar(0);\r
327                         GregorianCalendar cri = getCalendar(getCritDateTime());\r
328                         \r
329                         // 切り捨て条件の選択\r
330                         GregorianCalendar cond;\r
331                         if ( displayPassedReserve ) {\r
332                                 cond = (GregorianCalendar) cri.clone(); // 過去予約表示\r
333                         }\r
334                         else {\r
335                                 cond = (GregorianCalendar) cur.clone(); // 現在日時以上\r
336                         }\r
337                         \r
338                         // ループ終了位置\r
339                         GregorianCalendar cz = (GregorianCalendar) cur.clone();\r
340                         cz.add(Calendar.DATE, dogDays);\r
341                         \r
342                         // ループ開始位置\r
343                         GregorianCalendar ca = (GregorianCalendar) cri.clone();\r
344                         if ( isLateNight(r.getAhh()) ) {\r
345                                 ca.add(Calendar.DATE, 1);\r
346                         }\r
347                         ca.set(Calendar.HOUR_OF_DAY, Integer.valueOf(r.getAhh()));\r
348                         ca.set(Calendar.MINUTE, Integer.valueOf(r.getAmm()));\r
349                         GregorianCalendar cb = (GregorianCalendar) ca.clone();\r
350                         cb.set(Calendar.HOUR_OF_DAY, Integer.valueOf(r.getZhh()));\r
351                         cb.set(Calendar.MINUTE, Integer.valueOf(r.getZmm()));\r
352                         if ( cb.compareTo(ca) < 0 ) {\r
353                                 cb.add(Calendar.DATE, 1);       // 終了日時より開始日時が大きいならば\r
354                         }\r
355                         \r
356                         // 深夜かな?\r
357                         boolean islatenight = isLateNight(r.getAhh());\r
358                         \r
359                         while (ca.compareTo(cz) < 0)\r
360                         {\r
361                                 if ( cond.compareTo(cb) > 0 ) {\r
362                                         // 過去情報だにゅ\r
363                                         ca.add(Calendar.DATE, 1);\r
364                                         cb.add(Calendar.DATE, 1);\r
365                                         continue;\r
366                                 }\r
367                                 \r
368                                 boolean isReserved = false;     // 過去の予約=false\r
369 \r
370                                 if (ptnid == 10) {\r
371                                         // 毎日\r
372                                         isReserved = true;\r
373                                 }\r
374                                 else if (9 >= ptnid && ptnid >= 7) {\r
375                                         // 帯\r
376                                         int wd = ca.get(Calendar.DAY_OF_WEEK);\r
377                                         if ( islatenight ) {\r
378                                                 if ( adjLateNight ) {\r
379                                                         // RDなどの深夜時間帯(月~土)\r
380                                                         if ( Calendar.MONDAY <= wd && wd <= (r.getRec_pattern_id()-2) ) {\r
381                                                                 isReserved = true;\r
382                                                         }\r
383                                                 }\r
384                                                 else {\r
385                                                         // 通常の深夜時間帯(火~日)\r
386                                                         if ( Calendar.TUESDAY <= wd && wd <= (r.getRec_pattern_id()-1) ) {\r
387                                                                 isReserved = true;\r
388                                                         }\r
389                                                         else if ( ptnid == 9 && wd == Calendar.SUNDAY ) {\r
390                                                                 isReserved = true;\r
391                                                         }\r
392                                                 }\r
393                                         }\r
394                                         else {\r
395                                                 // 平常時間帯\r
396                                                 if ( Calendar.MONDAY <= wd && wd <= (r.getRec_pattern_id()-2) ) {\r
397                                                         isReserved = true;\r
398                                                 }\r
399                                         }\r
400                                 }\r
401                                 else if (ptnid < 7) {\r
402                                         // 週次\r
403                                         if ( ptnid == (ca.get(Calendar.DAY_OF_WEEK)-1) ) {\r
404                                                 isReserved = true;\r
405                                         }\r
406                                 }\r
407                                 \r
408                                 if (isReserved) {\r
409                                         GregorianCalendar ct = (GregorianCalendar) ca.clone();\r
410                                         ct.add(Calendar.MINUTE,len);\r
411                                         starts.add(getDateTime(ca));\r
412                                         ends.add(getDateTime(ct));\r
413                                 }\r
414                                 \r
415                                 ca.add(Calendar.DATE, 1);\r
416                                 cb.add(Calendar.DATE, 1);\r
417                         }\r
418                 }\r
419         }\r
420         \r
421         /**\r
422          * <P>aとbの差をミリ秒で返す(正/負)\r
423          * <P>秒に直すなら 1000、分に直すなら 60000で割る。\r
424          * @see #getDiffDateTime\r
425          */\r
426         public static long getCompareDateTime(String a, String b) {\r
427                 GregorianCalendar d = getCalendar(a);\r
428                 GregorianCalendar e = getCalendar(b);\r
429                 if ( d == null || e == null ) {\r
430                         return -1;\r
431                 }\r
432                 return getCompareDateTime(d.getTimeInMillis(), e.getTimeInMillis());\r
433         }\r
434 \r
435         /**\r
436          * <P>aとbの差をミリ秒で返す(正/負)\r
437          * <P>秒に直すなら 1000、分に直すなら 60000で割る。\r
438          * @see #getDiffDateTime\r
439          */\r
440         public static long getCompareDateTime(GregorianCalendar a, GregorianCalendar b) {\r
441                 return getCompareDateTime(a.getTimeInMillis(), b.getTimeInMillis());\r
442         }\r
443 \r
444         private static long getCompareDateTime(long x, long y) {\r
445                 return x-y;\r
446         }\r
447         \r
448         /**\r
449          * <P>aとbの差をミリ秒で返す(絶対値)\r
450          * <P>秒に直すなら 1000、分に直すなら 60000で割る。\r
451          * @see #getCompareDateTime\r
452          */\r
453         public static long getDiffDateTime(String a, String b) {\r
454                 GregorianCalendar d = getCalendar(a);\r
455                 GregorianCalendar e = getCalendar(b);\r
456                 if ( d == null || e == null ) {\r
457                         return -1;\r
458                 }\r
459                 return getDiffDateTime(d.getTimeInMillis(), e.getTimeInMillis());\r
460         }\r
461         \r
462         /**\r
463          * <P>aとbの差をミリ秒で返す\r
464          * <P>秒に直すなら 1000、分に直すなら 60000で割る。\r
465          */\r
466         public static long getDiffDateTime(GregorianCalendar a, GregorianCalendar b) {\r
467                 return getDiffDateTime(a.getTimeInMillis(), b.getTimeInMillis());\r
468         }\r
469         \r
470         private static long getDiffDateTime(long x, long y) {\r
471                 return ((x>y)?(x-y):(y-x));\r
472         }\r
473         \r
474 \r
475         /**\r
476          * 現在時刻+n秒のCalendarを返す\r
477          */\r
478         public static GregorianCalendar getCalendar(int n) {\r
479                 GregorianCalendar c = new GregorianCalendar();\r
480                 //c.setTime(new Date());\r
481                 c.add(Calendar.SECOND, n);\r
482                 return c;\r
483         }\r
484         /**\r
485          *  日付時刻文字列をCalendarに変換\r
486          *  @param date YYYY/MM/DD[(.)][ hh:mm[:ss]] or YYYY-MM-DD[Thh:mm[:ss]] or YYYYMMDD[hhmm[ss]]\r
487          */\r
488         public static GregorianCalendar getCalendar(String date) {\r
489                 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
490                 if ( ! ma.find()) {\r
491                         ma = Pattern.compile("^(\\d\\d\\d\\d)(\\d\\d)(\\d\\d)()?((\\d\\d)(\\d\\d)(\\d\\d)?)?$").matcher(date);\r
492                         if ( ! ma.find()) {\r
493                                 return null;\r
494                         }\r
495                 }\r
496                 \r
497                 GregorianCalendar c = null;\r
498                 if ( ma.group(5) == null ) {\r
499                         c = new GregorianCalendar(\r
500                                         Integer.valueOf(ma.group(1)),\r
501                                         Integer.valueOf(ma.group(2))-1,\r
502                                         Integer.valueOf(ma.group(3)),\r
503                                         0,\r
504                                         0,\r
505                                         0);\r
506                 }\r
507                 else {\r
508                         c = new GregorianCalendar(\r
509                                         Integer.valueOf(ma.group(1)),\r
510                                         Integer.valueOf(ma.group(2))-1,\r
511                                         Integer.valueOf(ma.group(3)),\r
512                                         Integer.valueOf(ma.group(6)),\r
513                                         Integer.valueOf(ma.group(7)),\r
514                                         0);\r
515                 }\r
516                 return c;\r
517         }\r
518         \r
519         /**\r
520          *  現在日時+n秒を日付時刻形式に変換。\r
521          *  @param n : 負の値を許可する\r
522          *  @return YYYY/MM/DD hh:mm\r
523          */\r
524         public static String getDateTime(int n) {\r
525                 GregorianCalendar c = new GregorianCalendar();\r
526                 //c.setTime(new Date());\r
527                 c.add(Calendar.SECOND, n);\r
528                 return getDateTime(c);\r
529         }\r
530         \r
531         /**\r
532          *  日時を日付時刻形式に変換。曜日文字がつかない。\r
533          *  @see #getDateTimeW(GregorianCalendar)\r
534          *  @see #getIsoDateTime(GregorianCalendar)\r
535          *  @see #getDateTimeYMD(GregorianCalendar)\r
536          *  @return YYYY/MM/DD hh:mm\r
537          */\r
538         public static String getDateTime(GregorianCalendar c) {\r
539                 return new SimpleDateFormat("yyyy/MM/dd HH:mm").format(c.getTime());\r
540         }\r
541         \r
542         /**\r
543          *  現在日時+n秒を日付時刻形式に変換。曜日文字がつく。\r
544          *  @param n : 負の値を許可する\r
545          *  @return YYYY/MM/DD hh:mm\r
546          */\r
547         public static String getDateTimeW(int n) {\r
548                 GregorianCalendar c = new GregorianCalendar();\r
549                 //c.setTime(new Date());\r
550                 c.add(Calendar.SECOND, n);\r
551                 return getDateTimeW(c);\r
552         }\r
553         \r
554         /**\r
555          *  日時を日付時刻形式に変換。曜日文字がつく。\r
556          *  @see #getDateTime(GregorianCalendar)\r
557          *  @return YYYY/MM/DD(WD) hh:mm\r
558          */\r
559         public static String getDateTimeW(GregorianCalendar c) {\r
560                 return new SimpleDateFormat("yyyy/MM/dd('"+WDTPTN[c.get(Calendar.DAY_OF_WEEK)-1]+"') HH:mm").format(c.getTime());\r
561         }\r
562         \r
563         /**\r
564          *  日時を日付時刻形式に変換。ISO形式。秒まで返却。\r
565          *  @see #getDateTime(GregorianCalendar)\r
566          *  @return YYYY-MM-DDThh:mm:ss\r
567          */\r
568         public static String getIsoDateTime(GregorianCalendar c) {\r
569                 return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(c.getTime());\r
570         }\r
571 \r
572         /**\r
573          *  現在日時+n秒を日付時刻形式に変換。\r
574          *  @see #getDateTime(GregorianCalendar)\r
575          *  @param n : 負の値を許可する\r
576          *  @return YYYYMMDDhhmmss\r
577          */\r
578         public static String getDateTimeYMD(int n) {\r
579                 GregorianCalendar c = new GregorianCalendar();\r
580                 //c.setTime(new Date());\r
581                 if (n != 0) c.add(Calendar.SECOND, n);\r
582                 return getDateTimeYMD(c);\r
583         }\r
584         \r
585         /**\r
586          *  日時を日付時刻形式に変換。YMD形式。秒まで返却。\r
587          *  @see #getDateTime(GregorianCalendar)\r
588          *  @return YYYYMMDDhhmmss\r
589          */\r
590         public static String getDateTimeYMD(GregorianCalendar c) {\r
591                 return new SimpleDateFormat("yyyyMMddHHmmss").format(c.getTime());\r
592         }\r
593 \r
594         /**\r
595          *  日時を日付時刻形式に変換。YMD形式。ミリ秒まで返却。\r
596          *  @see #getDateTime(GregorianCalendar)\r
597          *  @return YYYYMMDDhhmmssSSS\r
598          */\r
599         public static String getDateTimeYMDx(GregorianCalendar c) {\r
600                 return new SimpleDateFormat("yyyyMMddHHmmssSSS").format(c.getTime());\r
601         }\r
602 \r
603         /**\r
604          * <P>「当日」の日付文字列を返します。\r
605          * <P>ただし、05時~29時を当日として判断するので、<B>24時~29時に実行した場合は前日の日付が返ります</B>。\r
606          * @param n : 現在日時に対して n秒 加えた日時を返します。負の値も許可されます。\r
607          * @param addwdstr : trueの場合、日付に曜日文字[これ->(日)]を加えます。\r
608          * @return YYYY/MM/DD[(WD)] hh:mm:ss\r
609          */\r
610         public static String getDate529(int n, boolean addwdstr) {\r
611                 GregorianCalendar c = getCalendar(0);\r
612                 c.add(Calendar.SECOND, n);\r
613                 return getDate529(c, addwdstr);\r
614         }\r
615         /**\r
616          * @see #getDate529(int, boolean)\r
617          */\r
618         public static String getDate529(String s, boolean addwdstr) {\r
619                 GregorianCalendar c = getCalendar(s);\r
620                 return getDate529(c, addwdstr);\r
621         }\r
622         /**\r
623          * @see #getDate529(int, boolean)\r
624          */\r
625         public static String getDate529(GregorianCalendar c, boolean addwdstr) {\r
626                 // 今日の範囲は05:00~04:59まで\r
627                 if ( isLateNight(c.get(Calendar.HOUR_OF_DAY)) ) {\r
628                         c.add(Calendar.DAY_OF_MONTH, -1);\r
629                 }\r
630                 return getDate(c, addwdstr);\r
631         }\r
632         \r
633         /**\r
634          * 日付を日付形式に変換。\r
635          * @return YYYY/MM/DD(WD)\r
636          */ \r
637         public static String getDate(GregorianCalendar c) {\r
638                 return getDate(c, true);\r
639         }\r
640         \r
641         /**\r
642          * 日付を日付形式に変換。\r
643          * @param addwdstr : trueの場合、日付に曜日文字[これ->(日)]を加えます。\r
644          * @return YYYY/MM/DD[(WD)]\r
645          */ \r
646         public static String getDate(GregorianCalendar c, boolean addwdstr) {\r
647                 if ( addwdstr ) {\r
648                         return new SimpleDateFormat("yyyy/MM/dd('"+WDTPTN[c.get(Calendar.DAY_OF_WEEK)-1]+"')").format(c.getTime());\r
649                 }\r
650                 else {\r
651                         return new SimpleDateFormat("yyyy/MM/dd").format(c.getTime());\r
652                 }\r
653         }\r
654         \r
655         /**\r
656          * 日付を日付形式に変換。\r
657          * @return YYYY/MM/DD(WD)\r
658          */ \r
659         public static String getDate() {\r
660                 return getDate(getCalendar(0), true);\r
661         }\r
662         /**\r
663          * <P>「当日」の日付文字列を返します。\r
664          * <P>ただし、05時~29時を当日として判断するので、<B>24時~29時に実行した場合は前日の日付が返ります</B>。\r
665          * @param n : 現在日時に対して n秒 加えた日時を返します。負の値も許可されます。\r
666          * @return YYYYMMDD\r
667          */\r
668         public static String getDateYMD529(int n) {\r
669                 GregorianCalendar c = new GregorianCalendar();\r
670                 //c.setTime(new Date());\r
671                 c.add(Calendar.SECOND, n);\r
672                 \r
673                 // 今日の範囲は05:00~04:59まで\r
674                 if (c.get(Calendar.HOUR_OF_DAY) < 5) {\r
675                         c.add(Calendar.DAY_OF_MONTH, -1);\r
676                 }\r
677                 \r
678                 return getDateYMD(c);\r
679         }\r
680         \r
681         /**\r
682          * 現在日付を日付形式に変換。\r
683          * @param n : 負の値を許可する。\r
684          * @return YYYYMMDD\r
685          */\r
686         public static String getDateYMD(int n) {\r
687                 GregorianCalendar ca = CommonUtils.getCalendar(n);\r
688                 return getDateYMD(ca);\r
689         }\r
690         \r
691         /**\r
692          * 現在日付を日付形式に変換。\r
693          * @return YYYYMMDD\r
694          */\r
695         public static String getDateYMD(GregorianCalendar c) {\r
696                 return new SimpleDateFormat("yyyyMMdd").format(c.getTime());\r
697         }\r
698         \r
699         /**\r
700          *  日時を時刻形式に変換\r
701          * @return hh:mm\r
702          */\r
703         public static String getTime(int n) {\r
704                 return getTime(getCalendar(n));\r
705         }\r
706         \r
707         /**\r
708          *  日時を時刻形式に変換\r
709          * @return hh:mm\r
710          */\r
711         public static String getTime(GregorianCalendar c) {\r
712                 return getTime(c.get(Calendar.HOUR_OF_DAY),c.get(Calendar.MINUTE));\r
713         }\r
714         \r
715         /**\r
716          *  日時を時刻形式に変換\r
717          * @see #getTimeHM(GregorianCalendar)\r
718          * @return hh:mm\r
719          */\r
720         public static String getTime(int hh, int mm) {\r
721                 return String.format("%02d:%02d",hh,mm);\r
722         }\r
723         \r
724         /**\r
725          *  日時を時刻形式に変換\r
726          *  @see #getTime(GregorianCalendar)\r
727          * @return hhmm\r
728          */\r
729         public static String getTimeHM(int n) {\r
730                 return getTimeHM(getCalendar(n));\r
731         }\r
732         \r
733         /**\r
734          *  日時を時刻形式に変換\r
735          *  @see #getTime(GregorianCalendar)\r
736          * @return hhmm\r
737          */\r
738         public static String getTimeHM(GregorianCalendar c) {\r
739                 return getTimeHM(c.get(Calendar.HOUR_OF_DAY),c.get(Calendar.MINUTE));\r
740         }\r
741         \r
742         /**\r
743          *  日時を時刻形式に変換\r
744          *  @see #getTime(GregorianCalendar)\r
745          * @return hhmm\r
746          */\r
747         public static String getTimeHM(int hh, int mm) {\r
748                 return String.format("%02d%02d",hh,mm);\r
749         }\r
750         \r
751         /**\r
752          * 時間帯の重複があるかどうかを判定します。\r
753          * @param adjnotrep : falseの場合、終了時刻と開始時刻が重なるものを重複として扱います。\r
754          */\r
755         public static boolean isOverlap(String start1, String end1, String start2, String end2, boolean adjnotrep) {\r
756                 if ( adjnotrep ) {\r
757                         return( ! (end1.compareTo(start2) <= 0 || end2.compareTo(start1) <= 0));\r
758                 }\r
759                 else {\r
760                         return( ! (end1.compareTo(start2) < 0 || end2.compareTo(start1) < 0));\r
761                 }\r
762         }\r
763         \r
764         \r
765         /*******************************************************************************\r
766          * Color関連\r
767          ******************************************************************************/\r
768         \r
769         /**\r
770          * 文字列を色化します。\r
771          * @param s : 色化する文字列 "#xxxxxx;" (R、G、B 各16進2ケタ)\r
772          * @return {@link Color}\r
773          * @see #color2str(Color c)\r
774          */\r
775         public static Color str2color(String s) {\r
776                 try {\r
777                         Matcher ma = Pattern.compile("#(..)(..)(..)").matcher(s);\r
778                         if ( ma.find() ) {\r
779                                 int r = Integer.decode("0x"+ma.group(1));\r
780                                 int g = Integer.decode("0x"+ma.group(2));\r
781                                 int b = Integer.decode("0x"+ma.group(3));\r
782                                 return(new Color(r,g,b));\r
783                         }\r
784                         return new Color(0,0,0);\r
785                 }\r
786                 catch (NumberFormatException e) {\r
787                         e.printStackTrace();\r
788                 }\r
789                 return null;\r
790         }\r
791         \r
792         /**\r
793          * 色を文字列化します。\r
794          * @param c : 文字列化する色({@link Color})\r
795          * @return "#xxxxxx;" (R、G、B 各16進2ケタ)\r
796          * @see #str2color(String) \r
797          */\r
798         public static String color2str(Color c) {\r
799                 return String.format("#%02x%02x%02x", c.getRed(), c.getGreen(), c.getBlue());\r
800         }\r
801         \r
802         \r
803         /*******************************************************************************\r
804          * 文字列操作関連\r
805          ******************************************************************************/\r
806          \r
807         public static String joinPath(String... path) {\r
808                 return joinStr(File.separator, path);\r
809         }\r
810 \r
811         public static String joinStr(String s, ArrayList<String> a) {\r
812                 return joinStr(s,a.toArray(new String[0]));\r
813         }\r
814         \r
815         public static String joinStr(String s, String... a) {\r
816                 if (a.length <= 0) {\r
817                         return "";\r
818                 }\r
819                 StringBuffer sb = new StringBuffer();\r
820                 for (int i=0; i<a.length-1; i++) {\r
821                         sb.append(a[i]);\r
822                         sb.append(s);\r
823                 }\r
824                 sb.append(a[a.length-1]);\r
825                 return(sb.toString());\r
826         }\r
827         \r
828         /**\r
829          * 文字数ではなく、バイト数でのsubstringを行います。\r
830          * @param s\r
831          * @param length\r
832          * @return\r
833          */\r
834         public static String substringrb(String s, int length) {\r
835                 StringBuilder sb = new StringBuilder();\r
836                 int len = 0;\r
837                 for ( Character c : s.toCharArray() ) {\r
838                         len += (c<256)?(1):(2);\r
839                         if (len > length) {\r
840                                 break;\r
841                         }\r
842                         sb.append(c.toString());\r
843                 }\r
844                 return(sb.toString());\r
845         }\r
846         \r
847         private static final char[] NGCharList = "\\/:*?\"<>|".toCharArray();\r
848         \r
849         /**\r
850          * ファイル名に使用できない文字の一覧を返します。\r
851          */\r
852         public static String getNGCharList() {\r
853                 return new String(NGCharList);\r
854         }\r
855         \r
856         /**\r
857          * ファイル名に使用できない文字が含まれているかどうか判定します。\r
858          */\r
859         public static boolean isNGChar(String s) {\r
860                 for (int i=0; i<NGCharList.length; i++) {\r
861                         if (s.indexOf(NGCharList[i]) >= 0) {\r
862                                 return(true);\r
863                         }\r
864                 }\r
865                 return(false);\r
866         }\r
867         \r
868         /**\r
869          * ファイル名に使用できない文字をHTMLエスケープ(&#ddd;)します。\r
870          * @see #unEscape(String)\r
871          */\r
872         public static String escapeFilename(String src) {\r
873                 for (int i=0; i<NGCharList.length; i++) {\r
874                         src = src.replaceAll(String.format("\\%s",String.valueOf(NGCharList[i])), String.format("&#%03d;", (int)NGCharList[i]));\r
875                 }\r
876                 return src;\r
877         }\r
878 \r
879         /**\r
880          * HTMLエスケープをデコードします。\r
881          */\r
882         public static String unEscape(String src) {\r
883                 String dst = src.replaceAll("&quot;", "\"");\r
884                 dst = dst.replaceAll("&lt;", "<");\r
885                 dst = dst.replaceAll("&gt;", ">");\r
886                 dst = dst.replaceAll("&amp;", "&");\r
887                 dst = dst.replaceAll("&nbsp;", " ");\r
888                 dst = dst.replaceAll("〜", "~");\r
889                 dst = dst.replaceAll("−", "-");\r
890                 HashMap<String, String> ek = new HashMap<String, String>();\r
891                 Matcher ma = Pattern.compile("(&#(\\d+);)").matcher(src);\r
892                 while (ma.find()) {\r
893                         ek.put(ma.group(1), Character.valueOf((char)(int)Integer.valueOf(ma.group(2))).toString());\r
894                 }\r
895                 for (Entry<String, String> kv : ek.entrySet()) {\r
896                         dst = dst.replaceAll(kv.getKey(), kv.getValue());\r
897                 }\r
898                 return dst;\r
899         }\r
900         \r
901         public static String enEscape(String src) {\r
902                 StringBuilder sb = new StringBuilder();\r
903                 for ( int index=0; index<src.length(); index++ ) {\r
904                         char c = src.charAt(index);\r
905                         if ( c == '<' ) {\r
906                                 sb.append("&lt;");\r
907                         }\r
908                         else if ( c == '>' ) {\r
909                                 sb.append("&gt;");\r
910                         }\r
911                         else if ( c == '&' ) {\r
912                                 sb.append("&amp;");\r
913                         }\r
914                         else {\r
915                                 sb.append(c);\r
916                         }\r
917                 }\r
918                 return sb.toString();\r
919         }\r
920         \r
921         public static String decBr(String src) {\r
922                 String dst = src.replaceAll("<[bB][rR]\\s*/?>", "\n");\r
923                 return dst;\r
924         }\r
925         \r
926         /**\r
927          *  Unicodeエスケープをデコードします。\r
928          */\r
929         public static String unUniEscape(String src) {\r
930                 Matcher ma = Pattern.compile("\\\\u[0-9a-f]{4}").matcher(src);\r
931                 StringBuffer sb = new StringBuffer(src.length());\r
932                 while (ma.find()) {\r
933                         char[] chars = ma.group().substring(2, 6).toCharArray();\r
934                         int hex = 0;\r
935                         for (char c : chars) {\r
936                                 hex = hex << 4;\r
937                                 if ('a' <= c && c <= 'f') {\r
938                                         hex += c - 'a' + 10;\r
939                                 }\r
940                                 else {\r
941                                         hex += c - '0';\r
942                                 }\r
943                         }\r
944                         ma.appendReplacement(sb, ""+(char)hex);\r
945                 }\r
946                 ma.appendTail(sb);\r
947                 return sb.toString();\r
948         }\r
949         \r
950         \r
951         /**\r
952          * 文字列中の全角数字を半角数字に置き換えます\r
953          */\r
954         public static String toHANUM(String numTmp) {\r
955                 if (numTmp == null) return null;\r
956                 \r
957                 StringBuilder sb = new StringBuilder();\r
958                 for ( int i=0; i<numTmp.length(); i++ ) {\r
959                         char c = numTmp.charAt(i);\r
960                         if ( '0' <= c && c <= '9' ) {\r
961                                 c = (char)(c -  '0' + '0' );\r
962                         }\r
963                         sb.append(c);\r
964                 }\r
965                 return sb.toString();\r
966         }\r
967         \r
968         public static String toHANALNUM(String alnumTmp) {\r
969                 if (alnumTmp == null) return null;\r
970                 \r
971                 StringBuilder sb = new StringBuilder();\r
972                 for ( int i=0; i<alnumTmp.length(); i++ ) {\r
973                         char c = alnumTmp.charAt(i);\r
974                         if ( 'a' <= c && c <= 'z' ) {\r
975                                 c = (char)(c - 'a' + 'a' );\r
976                         }\r
977                         else if ( 'A' <= c && c <= 'Z' ) {\r
978                                 c = (char)(c -  'A' + 'A' );\r
979                         }\r
980                         else if ( '0' <= c && c <= '9' ) {\r
981                                 c = (char)(c -  '0' + '0' );\r
982                         }\r
983                         else if ( c == '(' ) {\r
984                                 c = '(';\r
985                         }\r
986                         else if ( c == ')' ) {\r
987                                 c = ')';\r
988                         }\r
989                         else if ( c == '-' ) {\r
990                                 c = '-';\r
991                         }\r
992                         else if ( c == ' ' ) {\r
993                                 c = ' ';\r
994                         }\r
995                         sb.append(c);\r
996                 }\r
997                 return sb.toString();\r
998         }\r
999 \r
1000         \r
1001         public static String getVerticalSplittedHTML(String text) {\r
1002                 if ( text == null ) {\r
1003                         return null;\r
1004                 }\r
1005                 \r
1006                 StringBuilder sb = new StringBuilder();\r
1007                 sb.append("<HTML>");\r
1008                 for ( int i=0; i<text.length(); i++ ) {\r
1009                         sb.append(text.charAt(i));\r
1010                         sb.append("<BR>");\r
1011                 }\r
1012                 int index = sb.lastIndexOf("<BR");\r
1013                 if ( index > 0 ) {\r
1014                         sb.delete(index,index+5);\r
1015                 }\r
1016                 sb.append("</HTML>");\r
1017                 \r
1018                 return sb.toString();\r
1019         }\r
1020         \r
1021         \r
1022         /*******************************************************************************\r
1023          * オブジェクト操作関連\r
1024          ******************************************************************************/\r
1025 \r
1026         /*******************************************************************************\r
1027          * JavaVM関連\r
1028          ******************************************************************************/\r
1029 \r
1030         /**\r
1031          * デバッグ用にスタックトレースをとりたいなー\r
1032          */\r
1033         public static void printStackTrace() {\r
1034                 if ( ! debug) return;\r
1035                 \r
1036                 new Throwable().printStackTrace();\r
1037         }\r
1038         \r
1039         /*******************************************************************************\r
1040          * OS操作関連\r
1041          ******************************************************************************/\r
1042 \r
1043         // なぜJavaなのに機種別のコードをかかなければならないのか…\r
1044         public static boolean isMac() { return ismac; }\r
1045         public static boolean isLinux() { return islinux; }\r
1046         public static boolean isWindows() { return iswindows; }\r
1047         public static boolean isWindowsXP() { return iswindowsxp; }\r
1048         \r
1049         private static final boolean ismac              = ((String)System.getProperty("os.name")).toLowerCase().replaceAll(" ", "").startsWith("macosx");\r
1050         private static final boolean islinux    = ((String)System.getProperty("os.name")).toLowerCase().replaceAll(" ", "").startsWith("linux");\r
1051         private static final boolean iswindows  = ((String)System.getProperty("os.name")).toLowerCase().replaceAll(" ", "").startsWith("windows");\r
1052         private static final boolean iswindowsxp= ((String)System.getProperty("os.name")).toLowerCase().replaceAll(" ", "").startsWith("windowsxp");\r
1053         \r
1054         // ミリ秒単位でsleep\r
1055         public static void milSleep(int i) {\r
1056                 try {\r
1057                         Thread.sleep(i);\r
1058                 }\r
1059                 catch (InterruptedException e) {\r
1060                         System.err.println("[スリープ] なんかあったのか");\r
1061                         e.printStackTrace();\r
1062                 }\r
1063         }\r
1064         \r
1065         /**\r
1066          * コマンドを実行する\r
1067          * @see #getCommandResult()\r
1068          * @param run : コマンドの指定\r
1069          * @return -1 : 失敗、-1以外 : コマンドのexit値\r
1070          */\r
1071         public static int executeCommand(String run)    {\r
1072                 \r
1073                 commandResult = null;\r
1074                 \r
1075                 ArrayList<String> list = new ArrayList<String>();\r
1076                 Matcher ma = Pattern.compile("((\"([^\"]*?)\"|([^\"]+?))(\\s+|$))").matcher(run);\r
1077                 while (ma.find()) {\r
1078                         if (ma.group(3) != null) {\r
1079                                 list.add(ma.group(3));\r
1080                         }\r
1081                         else {\r
1082                                 list.add(ma.group(4));\r
1083                         }\r
1084                 }\r
1085                 if ( list.size() == 0 ) {\r
1086                         System.err.println("[外部コマンド] 実行できません: "+run);\r
1087                         return -1;\r
1088                 }\r
1089                 else {\r
1090                         ProcessBuilder pb = null;\r
1091                         Process p = null;\r
1092                         \r
1093                         InputStream is = null;\r
1094                         InputStreamReader isr = null;\r
1095                         BufferedReader br =  null;\r
1096         \r
1097                         try {\r
1098                                 pb = new ProcessBuilder(list);\r
1099                                 pb.redirectErrorStream(true);\r
1100                                 \r
1101                                 p = pb.start();\r
1102                                 p.getOutputStream().close();    // 入力はしない\r
1103                                 \r
1104                                 String encoding = (isWindows())?("MS932"):("UTF-8");\r
1105                                 \r
1106                                 StringBuilder sb = new StringBuilder();\r
1107                                 is = p.getInputStream();\r
1108                                 isr = new InputStreamReader(is,encoding);\r
1109                                 br =  new BufferedReader(isr);\r
1110                                 String s;\r
1111                                 while ((s=br.readLine()) != null) {\r
1112                                         sb.append(s);\r
1113                                         sb.append("\n");\r
1114                                 }\r
1115                                 commandResult = sb.toString();\r
1116                                 \r
1117                                 System.out.println("--- 外部コマンドを実行します ---");\r
1118                                 System.out.println(commandResult);\r
1119                                 System.out.println("--- 外部コマンドを実行しました ---");\r
1120                                 \r
1121                                 p.waitFor();    // is.read()で判定できるので不要\r
1122                                 \r
1123                                 int retval = p.exitValue();\r
1124                                 \r
1125                                 return retval;\r
1126                         }\r
1127                         catch ( IOException e ) {\r
1128                                 System.err.println("[外部コマンド] 失敗しました: "+run);\r
1129                                 e.printStackTrace();\r
1130                         }\r
1131                         catch ( InterruptedException e ) {\r
1132                                 System.err.println("[外部コマンド] 失敗しました: "+run);\r
1133                                 e.printStackTrace();\r
1134                         }\r
1135                         finally {\r
1136                                 closing(br);\r
1137                                 closing(isr);\r
1138                                 closing(is);\r
1139                                 \r
1140                                 if ( p != null ) {\r
1141                                         closing(p.getInputStream());\r
1142                                         closing(p.getErrorStream());\r
1143                                         p.destroy();\r
1144                                 }\r
1145                         }\r
1146                 }\r
1147                 \r
1148                 return -1;\r
1149         }\r
1150         \r
1151         public static String getCommandResult() { return commandResult; }\r
1152         \r
1153         private static String commandResult;\r
1154 \r
1155         /**\r
1156          * 登録されたアプリケーションでファイルを開く\r
1157          */\r
1158         public static String openFile(String file)      {\r
1159                 String errmsg = null;\r
1160                 try {\r
1161                         if ( useRundll32 && isWindows() ) {\r
1162                                 Runtime runtime = Runtime.getRuntime(); \r
1163                                 runtime.exec("rundll32 url.dll,FileProtocolHandler "+new File(file).getAbsolutePath());\r
1164                         }\r
1165                         else {\r
1166                                 Desktop desktop = Desktop.getDesktop();\r
1167                                 desktop.open(new File(file));\r
1168                         }\r
1169                 }\r
1170                 catch (UnsupportedOperationException e) {\r
1171                         System.err.println("[アプリケーションでファイルを開く] 失敗しました: "+file);\r
1172                         e.printStackTrace();\r
1173                         errmsg = e.toString();\r
1174                 }\r
1175                 catch (IOException e) {\r
1176                         System.err.println("[アプリケーションでファイルを開く] 失敗しました: "+file);\r
1177                         e.printStackTrace();\r
1178                         errmsg = e.toString();\r
1179                 }\r
1180                 return errmsg;\r
1181         }\r
1182         \r
1183         \r
1184         /*******************************************************************************\r
1185          * ファイルI/O関連\r
1186          ******************************************************************************/\r
1187         \r
1188         // 古くないかどうか\r
1189         public static boolean isFileAvailable(File f, int days) {\r
1190                 // 存在するか\r
1191                 if ( ! f.exists() ) {\r
1192                         return false;\r
1193                 }\r
1194                 \r
1195                 // 最近更新されているか\r
1196                 long lm = f.lastModified();\r
1197                 GregorianCalendar cal = new GregorianCalendar();\r
1198                 cal.setTimeInMillis(lm);\r
1199                 if ( getCompareDateTime(cal, getCalendar(-days*86400)) < 0 ) {\r
1200                         return false;\r
1201                 }\r
1202                         \r
1203                 return true;\r
1204         }\r
1205         \r
1206         // ディレクトリをまるっと削除\r
1207         public static boolean rmdir(File f) {\r
1208                 if( ! f.exists()) {\r
1209                         return false;\r
1210                 }\r
1211                 \r
1212                 if (f.isFile()){\r
1213                         return f.delete();\r
1214                 }\r
1215                 else if (f.isDirectory()) {\r
1216                         File[] files = f.listFiles();\r
1217                         for (File file : files){\r
1218                                 if ( ! rmdir(file)) {\r
1219                                         return false;\r
1220                                 }\r
1221                         }\r
1222                         return f.delete();\r
1223                 }\r
1224                 \r
1225                 return false;   // ここには来ないはず\r
1226         }\r
1227         \r
1228         // カウンタの記録\r
1229         public static boolean saveCnt(int cnt, String filename) {\r
1230                 if ( ! write2file(filename, String.valueOf(cnt)) ) {\r
1231                         System.out.println("[カウンタファイル] 書き込めませんでした: "+filename);\r
1232                         return false;\r
1233                 }\r
1234                 return true;\r
1235         }\r
1236         public static int loadCnt(String filename) {\r
1237                 if ( ! new File(filename).exists() ) {\r
1238                         return -1;\r
1239                 }\r
1240                 \r
1241                 try {\r
1242                         String str = read4file(filename, true);\r
1243                         if ( str != null ) {\r
1244                                 return Integer.valueOf(str);\r
1245                         }\r
1246                 }\r
1247                 catch ( NumberFormatException e ) {\r
1248                         System.err.println("[カウンタファイル] 内容が不正です: "+filename);\r
1249                 }\r
1250                 \r
1251                 System.err.println("[カウンタファイル] 読み込めませんでした: "+filename);\r
1252                 return -1;\r
1253         }\r
1254         \r
1255         // ロック・アンロック\r
1256         \r
1257         /**\r
1258          *  ロック\r
1259          */\r
1260         public static boolean getLock() {\r
1261                 FileOutputStream fos = null;\r
1262                 FileChannel fc = null;\r
1263                 try {\r
1264                         fos = new FileOutputStream(new File("_lock_"));\r
1265                         fc = fos.getChannel();\r
1266                         lock = fc.tryLock();\r
1267                         if ( lock == null ) {\r
1268                                 System.err.println("[多重起動禁止] ロックされています.");\r
1269                                 return false;\r
1270                         }\r
1271                         else {\r
1272                                 return true;\r
1273                         }\r
1274                 }\r
1275                 catch (FileNotFoundException e) {\r
1276                         System.err.println("[多重起動禁止] ロックの取得に失敗しました.");\r
1277                         e.printStackTrace();\r
1278                 }\r
1279                 catch (IOException e) {\r
1280                         System.err.println("[多重起動禁止] ロックの取得に失敗しました.");\r
1281                         e.printStackTrace();\r
1282                 }\r
1283                 finally {\r
1284                         //closing(fos);\r
1285                         //closing(fc);\r
1286                 }\r
1287                 return false;\r
1288         }\r
1289         \r
1290         /**\r
1291          *  アンロック\r
1292          */\r
1293         public static void getUnlock() {\r
1294                 try {\r
1295                         if ( lock != null ) {\r
1296                                 lock.release();\r
1297                         }\r
1298                 } catch (IOException e) {\r
1299                         System.err.println("[多重起動禁止] ロックの解放に失敗しました.");\r
1300                         e.printStackTrace();\r
1301                 }\r
1302         }\r
1303 \r
1304         private static FileLock lock = null;\r
1305 \r
1306         /**\r
1307          *  テキストをファイルに書き出す(エンコードはデフォルト)\r
1308          */\r
1309         public static boolean write2file(String fname, String dat) {\r
1310                 return write2file(fname, dat, null);\r
1311         }\r
1312         \r
1313         /**\r
1314          *  テキストをファイルに書き出す(エンコードは指定による)\r
1315          */\r
1316         public static boolean write2file(String fname, String dat, String encoding) {\r
1317                 if ( fname.matches(".*\\.zip$") ) {\r
1318                         return _write2zip(fname, dat, encoding);\r
1319                 }\r
1320                 else {\r
1321                         return _write2file(fname, dat, encoding);\r
1322                 }\r
1323         }\r
1324         private static boolean _write2zip(String fname, String dat, String encoding) {\r
1325                 {\r
1326                         FileOutputStream os = null;\r
1327                         BufferedOutputStream bos = null;\r
1328                         ZipOutputStream zos = null;\r
1329                         try {\r
1330                                 // 一時ファイルに書き出し\\r
1331                                 os = new FileOutputStream(fname+".tmp");\r
1332                                 bos = new BufferedOutputStream(os);\r
1333                                 zos = new ZipOutputStream(bos);\r
1334                                 \r
1335                                 byte[] buf = null;\r
1336                                 if ( encoding == null ) {\r
1337                                         // デフォルトエンコーディングで\r
1338                                         buf = dat.getBytes();\r
1339                                 }\r
1340                                 else {\r
1341                                         // 指定エンコーディングで\r
1342                                         buf = dat.getBytes(encoding);\r
1343                                 }\r
1344                                 \r
1345                                 ZipEntry ze = new ZipEntry(ZIPENTRY);\r
1346                                 ze.setSize(buf.length);\r
1347                                 \r
1348                                 zos.putNextEntry(ze);\r
1349                                 zos.write(buf);\r
1350                                 \r
1351                         // 処理が続くので閉じないとアカン!\r
1352                                 zos.closeEntry();\r
1353                             zos.close(); zos = null;\r
1354                         if (bos!=null) { bos.close(); bos = null; }\r
1355                         if (os!=null) { os.close(); os = null; }\r
1356                                 \r
1357                                 // キャッシュファイルに変換\r
1358                             File o = new File(fname);\r
1359                             if ( o.exists() && ! o.delete() ) {\r
1360                                 System.err.println("削除できないよ: "+fname);\r
1361                             }\r
1362                             File n = new File(fname+".tmp");\r
1363                             if ( ! n.renameTo(o) ) {\r
1364                                 System.err.println("リネームできないよ: "+fname);\r
1365                             }\r
1366                         }\r
1367                         catch (Exception e) {\r
1368                                 // 例外\r
1369                                 System.out.println("書けないよ: "+e.toString());\r
1370                                 return false;\r
1371                         }\r
1372                         finally {\r
1373                                 closing(zos);\r
1374                                 closing(bos);\r
1375                                 closing(os);\r
1376                         }\r
1377                 }\r
1378                 return true;\r
1379         }\r
1380         private static boolean _write2file(String fname, String dat, String encoding) {\r
1381                 {\r
1382                         Writer wr = null;\r
1383                         BufferedWriter bw = null;\r
1384                         FileOutputStream os = null;\r
1385                         try {\r
1386                                 // 一時ファイルに書き出し\r
1387                                 if ( encoding == null ) {\r
1388                                         // デフォルトエンコーディングで\r
1389                                         wr = new FileWriter(fname+".tmp");\r
1390                                 }\r
1391                                 else {\r
1392                                         // 指定エンコーディングで\r
1393                                         os = new FileOutputStream(new File(fname+".tmp"));\r
1394                                         wr = new OutputStreamWriter(os, encoding); \r
1395                                 }\r
1396                                 bw = new BufferedWriter(wr);\r
1397                         bw.write(dat);\r
1398                         \r
1399                         // 処理が続くので閉じないとアカン!\r
1400                             bw.close(); bw = null;\r
1401                         wr.close(); wr = null;\r
1402                         if (os!=null) { os.close(); os = null; }\r
1403                                 \r
1404                                 // キャッシュファイルに変換\r
1405                             File o = new File(fname);\r
1406                             if ( o.exists() && ! o.delete() ) {\r
1407                                 System.err.println("削除できないよ: "+fname);\r
1408                             }\r
1409                             File n = new File(fname+".tmp");\r
1410                             if ( ! n.renameTo(o) ) {\r
1411                                 System.err.println("リネームできないよ: "+fname);\r
1412                             }\r
1413                         }\r
1414                         catch (Exception e) {\r
1415                                 // 例外\r
1416                                 System.out.println("書けないよ: "+e.toString());\r
1417                                 return false;\r
1418                         }\r
1419                         finally {\r
1420                                 closing(bw);\r
1421                                 closing(wr);\r
1422                                 closing(os);\r
1423                         }\r
1424                 }\r
1425                 return true;\r
1426         }\r
1427         \r
1428         private static final String ZIPENTRY = "compressed.dat";\r
1429         \r
1430         /**\r
1431          *  テキストをファイルを読み出す(エンコードはデフォルト)\r
1432          */\r
1433         public static String read4file(String fname, boolean nocr) {\r
1434                 return read4file(fname, nocr, null);\r
1435         }\r
1436 \r
1437         /**\r
1438          *  テキストをファイルを読み出す(エンコードは指定による)\r
1439          */\r
1440         public static String read4file(String fname, boolean nocr, String encoding) {\r
1441                 if ( fname.matches(".*\\.zip$") ) {\r
1442                         return _read4zip(fname, nocr, null);\r
1443                 }\r
1444                 else {\r
1445                         return _read4file(fname, nocr, null);\r
1446                 }\r
1447         }\r
1448         private static String _read4zip(String fname, boolean nocr, String encoding) {\r
1449                 String response = null;\r
1450                 {\r
1451                         ZipFile zf = null;\r
1452                         Reader rd = null;\r
1453                         InputStream is = null;\r
1454                         BufferedReader br = null;\r
1455                         try {\r
1456                                 // ファイルから読み出し\r
1457                                 zf = new ZipFile(fname);\r
1458                                 ZipEntry ze = zf.getEntry(ZIPENTRY);\r
1459                                 if ( ze == null ) {\r
1460                                         System.out.println("ZIPファイルがおかしい");\r
1461                                         return null;\r
1462                                 }\r
1463                                 \r
1464                                 is = zf.getInputStream(ze);\r
1465                                 \r
1466                                 // ファイルから読み出し\r
1467                                 if ( encoding == null ) {\r
1468                                         // デフォルトエンコーディングで\r
1469                                         rd = new InputStreamReader(is); \r
1470                                 }\r
1471                                 else {\r
1472                                         // 指定エンコーディングで\r
1473                                         rd = new InputStreamReader(is, encoding); \r
1474                                 }\r
1475                                 br = new BufferedReader(rd);\r
1476                                 \r
1477                                 String str;\r
1478                                 StringBuilder sb = new StringBuilder();\r
1479                                 while ((str = br.readLine()) != null) {\r
1480                                         sb.append(str);\r
1481                                         if ( ! nocr ) sb.append("\n");\r
1482                                 }\r
1483                                 \r
1484                                 response = sb.toString();\r
1485                         }\r
1486                         catch (Exception e) {\r
1487                                 // 例外\r
1488                                 System.out.println("読めないよ: "+e.toString());\r
1489                                 return null;\r
1490                         }\r
1491                         finally {\r
1492                                 closing(is);\r
1493                                 closing(br);\r
1494                                 closing(rd);\r
1495                                 closing(zf);\r
1496                         }\r
1497                 }\r
1498                 return response;\r
1499         }\r
1500         private static String _read4file(String fname, boolean nocr, String encoding) {\r
1501                 String response = null;\r
1502                 {\r
1503                         Reader rd = null;\r
1504                         BufferedReader br = null;\r
1505                         FileInputStream is = null;\r
1506                         try {\r
1507                                 // ファイルから読み出し\r
1508                                 if ( encoding == null ) {\r
1509                                         // デフォルトエンコーディングで\r
1510                                         rd = new FileReader(fname);\r
1511                                 }\r
1512                                 else {\r
1513                                         // 指定エンコーディングで\r
1514                                         is = new FileInputStream(new File(fname));\r
1515                                         rd = new InputStreamReader(is, encoding); \r
1516                                 }\r
1517                                 br = new BufferedReader(rd);\r
1518                                 \r
1519                                 String str;\r
1520                                 StringBuilder sb = new StringBuilder();\r
1521                                 while ((str = br.readLine()) != null) {\r
1522                                         sb.append(str);\r
1523                                         if ( ! nocr ) sb.append("\n");\r
1524                                 }\r
1525                                 \r
1526                                 response = sb.toString();\r
1527                         }\r
1528                         catch (Exception e) {\r
1529                                 // 例外\r
1530                                 System.out.println("読めないよ: "+e.toString());\r
1531                                 return null;\r
1532                         }\r
1533                         finally {\r
1534                                 closing(br);\r
1535                                 closing(rd);\r
1536                                 closing(is);\r
1537                         }\r
1538                 }\r
1539                 return response;\r
1540         }\r
1541 \r
1542         /**\r
1543          *  XMLEncoderでシリアライズしてファイルに出力する\r
1544          */\r
1545         public static boolean writeXML(String fname, Object obj) {\r
1546                 boolean done = true;\r
1547                 {\r
1548                         FileOutputStream fos = null;\r
1549                         BufferedOutputStream bos = null;\r
1550                         XMLEncoder enc = null;\r
1551                         try {\r
1552                                 fos = new FileOutputStream(fname+".tmp");\r
1553                                 bos = new BufferedOutputStream(fos);\r
1554                                 enc = new XMLEncoder(bos);\r
1555                                 enc.writeObject(obj);\r
1556                                 \r
1557                         // 処理が続くので閉じないとアカン!\r
1558                                 enc.close(); enc = null;\r
1559                                 bos.close(); bos = null;\r
1560                                 fos.close(); fos = null;\r
1561                                 \r
1562                                 // キャッシュファイルに変換\r
1563                             File o = new File(fname);\r
1564                             if ( o.exists() && ! o.delete() ) {\r
1565                                 System.err.println("削除できないよ: "+fname);\r
1566                             }\r
1567                             File n = new File(fname+".tmp");\r
1568                             if ( ! n.renameTo(o) ) {\r
1569                                 System.err.println("リネームできないよ: "+fname);\r
1570                             }\r
1571                         }\r
1572                         catch (Exception e) {\r
1573                                 // 例外\r
1574                                 done = false;\r
1575                                 System.err.println(e.toString());\r
1576                         }\r
1577                         finally {\r
1578                                 closing(enc);\r
1579                                 closing(fos);\r
1580                                 closing(bos);\r
1581                         }\r
1582                 }\r
1583                 return done;\r
1584         }\r
1585         \r
1586         /**\r
1587          * XMLDecorderでシリアライズしたファイルを読みだす(オブジェクトを返す場合)\r
1588          */\r
1589         public static Object readXML(String fname) {\r
1590                 {\r
1591                         XMLDecoder dec = null;\r
1592                         FileInputStream fis = null;\r
1593                         BufferedInputStream bis = null;\r
1594                         try {\r
1595                                 fis = new FileInputStream(fname);\r
1596                                 bis = new BufferedInputStream(fis);\r
1597                                 dec = new XMLDecoder(bis);\r
1598                                 return dec.readObject();\r
1599                         }\r
1600                         catch (Exception e) {\r
1601                                 // 例外\r
1602                                 System.err.println(e.toString());\r
1603                         }\r
1604                         finally {\r
1605                                 closing(dec);\r
1606                                 closing(bis);\r
1607                                 closing(fis);\r
1608                         }\r
1609                 }\r
1610                 return null;\r
1611         }\r
1612         \r
1613         /**\r
1614          * XMLDecorderでシリアライズしたファイルを読みだす(既存のオブジェクトに値を入れて返す場合)\r
1615          */\r
1616         public static boolean readXML(String fname, Object obj) {\r
1617                 \r
1618                 Object tmp = readXML(fname);\r
1619                 if ( tmp == null ) {\r
1620                         return false;\r
1621                 }\r
1622                 \r
1623                 return FieldUtils.deepCopy(obj, tmp);\r
1624         }\r
1625 \r
1626         /*\r
1627          * finallyブロックで書き間違えそうなので\r
1628          */\r
1629         public static void closing(Reader r) {\r
1630                 if ( r != null ) try { r.close(); } catch (Exception e) {}\r
1631         }\r
1632         public static void closing(InputStream r) {\r
1633                 if ( r != null ) try { r.close(); } catch (Exception e) {}\r
1634         }\r
1635         public static void closing(ZipFile r) {\r
1636                 if ( r != null ) try { r.close(); } catch (Exception e) {}\r
1637         }\r
1638         public static void closing(XMLDecoder r) {\r
1639                 if ( r != null ) r.close();\r
1640         }\r
1641         \r
1642         public static void closing(Writer w) {\r
1643                 if ( w != null ) try { w.close(); } catch (Exception e) {}\r
1644         }\r
1645         public static void closing(OutputStream w) {\r
1646                 if ( w != null ) try { w.close(); } catch (Exception e) {}\r
1647         }\r
1648         public static void closing(XMLEncoder w) {\r
1649                 if ( w != null ) w.close();\r
1650         }\r
1651         \r
1652         public static void closing(FileChannel fc) {\r
1653                 if ( fc != null ) try { fc.close(); } catch (Exception e) {}\r
1654         }\r
1655         \r
1656         public static void closing(Socket sock) {\r
1657                 if ( sock != null ) try { sock.close(); } catch (Exception e) {}\r
1658         }\r
1659         public static void closing(HttpURLConnection ucon) {\r
1660                 if ( ucon != null ) ucon.disconnect();\r
1661         }\r
1662 }\r