OSDN Git Service

8910fed99ab2aa0665553666267a789820dcc234
[jindolf/JinArchiver.git] / src / main / java / jp / sourceforge / jindolf / archiver / FileArchive.java
1 /*\r
2  * file archive utilities\r
3  *\r
4  * Copyright(c) 2008 olyutorskii\r
5  */\r
6 \r
7 package jp.sourceforge.jindolf.archiver;\r
8 \r
9 import java.io.File;\r
10 import java.io.IOException;\r
11 import java.io.InputStream;\r
12 import java.io.InputStreamReader;\r
13 import java.io.LineNumberReader;\r
14 import java.io.Reader;\r
15 import java.net.MalformedURLException;\r
16 import java.net.URI;\r
17 import java.net.URL;\r
18 import java.text.DateFormat;\r
19 import java.text.ParseException;\r
20 import java.text.SimpleDateFormat;\r
21 import java.util.Date;\r
22 import java.util.LinkedList;\r
23 import java.util.List;\r
24 import java.util.Locale;\r
25 import java.util.regex.Matcher;\r
26 import java.util.regex.Pattern;\r
27 import jp.sourceforge.jindolf.corelib.LandDef;\r
28 import jp.sourceforge.jindolf.corelib.PeriodType;\r
29 \r
30 /**\r
31  * ファイルシステム上に納められた\r
32  * 生XHTMLデータおよびログファイルへのアクセス諸々。\r
33  */\r
34 public final class FileArchive{\r
35 \r
36     private static final Pattern LINE_PATTERN;\r
37     private static final DateFormat ISO_FORMAT;\r
38 \r
39     static{\r
40         String fnameRegex =\r
41                  "(jin_([^_]+)_(\\d+)_(\\d+)_"\r
42                 +"(?:(prologue)|(progress)|(epilogue))"\r
43                 +"\\.html)";\r
44         LINE_PATTERN = Pattern.compile(\r
45             "^" + fnameRegex + "\\s+(\\S+)\\s+(\\S+)\\s+(\\d)" + "$");\r
46 \r
47         ISO_FORMAT =\r
48                 new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.JAPAN);\r
49     }\r
50 \r
51     /**\r
52      * ISO形式の日付時刻情報をパースする。\r
53      * @param text 日付表記\r
54      * @return エポック秒(ms)\r
55      */\r
56     public static long parseISODate(String text){\r
57         Date date;\r
58         try{\r
59             synchronized(ISO_FORMAT){\r
60                 date = ISO_FORMAT.parse(text);\r
61             }\r
62         }catch(ParseException e){\r
63             throw new IllegalArgumentException(e);\r
64         }\r
65         return date.getTime();\r
66     }\r
67 \r
68     /**\r
69      * ログ記述からリソース情報を生成する。\r
70      * @param logLine 1行に納められたログ記述\r
71      * @return リソース情報\r
72      */\r
73     public static PeriodResource parseDownLogLine(CharSequence logLine){\r
74         PeriodResource result;\r
75 \r
76         Matcher matcher = LINE_PATTERN.matcher(logLine);\r
77         if( ! matcher.matches() ) throw new IllegalArgumentException();\r
78 \r
79         String fname = matcher.group(1);\r
80         String landId = matcher.group(2);\r
81         int villageId = Integer.parseInt(matcher.group(3));\r
82         int day = Integer.parseInt(matcher.group(4));\r
83 \r
84         PeriodType periodType;\r
85         if     (matcher.start(5) >= 0) periodType = PeriodType.PROLOGUE;\r
86         else if(matcher.start(6) >= 0) periodType = PeriodType.PROGRESS;\r
87         else if(matcher.start(7) >= 0) periodType = PeriodType.EPILOGUE;\r
88         else throw new IllegalArgumentException();\r
89 \r
90         String uriText = matcher.group(8);\r
91         String dateText = matcher.group(9);\r
92         int hasError = Integer.parseInt(matcher.group(10));\r
93         if(hasError != 0) throw new IllegalArgumentException();\r
94 \r
95         long dateMs = parseISODate(dateText);\r
96 \r
97         if(landId.equals("wolf0")) landId = "wolf";\r
98         if(landId.equals("wolf1")) landId = "wolf0";\r
99         LandDef landDef = JinArchiver.getLandDef(landId);\r
100 \r
101         File file = new File(fname);\r
102         URI fileUri = file.toURI();\r
103         URL fileUrl;\r
104         try{\r
105             fileUrl = fileUri.toURL();\r
106         }catch(MalformedURLException e){\r
107             throw new IllegalArgumentException(e);\r
108         }\r
109 \r
110         result = new PeriodResource(landDef,\r
111                                     villageId,\r
112                                     periodType,\r
113                                     day,\r
114                                     uriText,\r
115                                     dateMs,\r
116                                     fileUrl );\r
117 \r
118         return result;\r
119     }\r
120 \r
121     /**\r
122      * ログファイルからリソース列を抽出する。\r
123      * @param reader ログファイルの内容\r
124      * @return リソース列\r
125      * @throws IOException 入力エラー\r
126      */\r
127     public static List<PeriodResource> parseDownList(LineNumberReader reader)\r
128             throws IOException{\r
129         List<PeriodResource> result = new LinkedList<PeriodResource>();\r
130 \r
131         for(;;){\r
132             String line = reader.readLine();\r
133             if(line == null) break;\r
134             PeriodResource info = parseDownLogLine(line);\r
135             if(info == null){\r
136                 throw new IllegalArgumentException();\r
137             }\r
138             result.add(info);\r
139         }\r
140 \r
141         return result;\r
142     }\r
143 \r
144     /**\r
145      * ログファイルからリソース列を抽出する。\r
146      * @param istream ログファイルの内容\r
147      * @return リソース列\r
148      * @throws IOException 入力エラー\r
149      */\r
150     public static List<PeriodResource> parseDownloadLog(InputStream istream)\r
151             throws IOException{\r
152         Reader reader = new InputStreamReader(istream, "US-ASCII");\r
153         LineNumberReader lineReader = new LineNumberReader(reader);\r
154         List<PeriodResource> result = parseDownList(lineReader);\r
155         lineReader.close();\r
156         return result;\r
157     }\r
158 \r
159     /**\r
160      * 隠れコンストラクタ。\r
161      */\r
162     private FileArchive(){\r
163         throw new Error();\r
164     }\r
165 \r
166 }\r