OSDN Git Service

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