OSDN Git Service

RCS風キーワード展開の抑止。
[jindolf/JinArchiver.git] / src / main / java / jp / sourceforge / jindolf / archiver / JinArchiver.java
1 /*\r
2  * main entry\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.BufferedOutputStream;\r
10 import java.io.BufferedWriter;\r
11 import java.io.File;\r
12 import java.io.FileOutputStream;\r
13 import java.io.IOException;\r
14 import java.io.OutputStream;\r
15 import java.io.OutputStreamWriter;\r
16 import java.io.Writer;\r
17 import java.text.MessageFormat;\r
18 import java.util.List;\r
19 import javax.xml.parsers.DocumentBuilder;\r
20 import javax.xml.parsers.DocumentBuilderFactory;\r
21 import jp.sourceforge.jindolf.corelib.LandDef;\r
22 import jp.sourceforge.jindolf.parser.DecodeException;\r
23 import jp.sourceforge.jindolf.parser.HtmlParseException;\r
24 \r
25 /**\r
26  * メインエントリ。\r
27  */\r
28 public final class JinArchiver{\r
29     /** Generator. */\r
30     public static final String GENERATOR = "JinArchiver 1.401.2";\r
31     private static final List<LandDef> LANDDEF_LIST;\r
32 \r
33     static{\r
34         DocumentBuilderFactory factory =\r
35                 DocumentBuilderFactory.newInstance();\r
36         try{\r
37             DocumentBuilder builder = factory.newDocumentBuilder();\r
38             LANDDEF_LIST = LandDef.buildLandDefList(builder);\r
39         }catch(RuntimeException e){\r
40             throw e;\r
41         }catch(Exception e){\r
42             throw new ExceptionInInitializerError(e);\r
43         }\r
44     }\r
45 \r
46     /**\r
47      * 国IDから国情報を得る。\r
48      * @param landId 国ID\r
49      * @return 国情報\r
50      */\r
51     public static LandDef getLandDef(String landId){\r
52         for(LandDef landDef : LANDDEF_LIST){\r
53             if(landDef.getLandId().equals(landId)) return landDef;\r
54         }\r
55         return null;\r
56     }\r
57 \r
58     /**\r
59      * ヘルプメッセージ出力。\r
60      */\r
61     private static void helpMessage(){\r
62         System.err.println(\r
63                 "\n" + GENERATOR + " 人狼BBS アーカイブ作成ツール\n\n"\r
64                 +"-h, -help, -?\n\tヘルプメッセージ\n"\r
65                 +"-land 国識別子\n"\r
66                 +"-vid 村番号\n"\r
67                 +"-outdir 出力ディレクトリ\n"\r
68                 +"-stdout\n\t標準出力へ出力\n\n"\r
69                 +"※ -outdir と -stdout は排他指定\n"\r
70                 );\r
71         StringBuilder landList = new StringBuilder();\r
72         for(LandDef landDef : LANDDEF_LIST){\r
73             landList.append(landDef.getLandId()).append(' ');\r
74         }\r
75         System.err.print("利用可能な国識別子は ");\r
76         System.err.println(landList);\r
77         System.err.println();\r
78         return;\r
79     }\r
80 \r
81     /**\r
82      * オプション文字列を解析する。\r
83      * @param args オプション文字列\r
84      */\r
85     private static void parseOption(String[] args){\r
86         if(args.length <= 0){\r
87             helpMessage();\r
88             System.exit(0);\r
89             return;\r
90         }\r
91 \r
92         LandDef landDef = null;\r
93         int vid = -1;\r
94         String outdir = null;\r
95         boolean stdout = false;\r
96 \r
97         for(int pos = 0; pos < args.length; pos++){\r
98             String arg = args[pos];\r
99 \r
100             if( ! arg.startsWith("-") ){\r
101                 System.err.println("不正なオプションです。 " + arg);\r
102                 System.exit(1);\r
103                 return;\r
104             }\r
105 \r
106             if(arg.equals("-h") || arg.equals("-help") || arg.equals("-?")){\r
107                 helpMessage();\r
108                 System.exit(0);\r
109                 return;\r
110             }\r
111 \r
112             if(arg.equals("-stdout")){\r
113                 stdout = true;\r
114                 outdir = null;\r
115                 continue;\r
116             }\r
117 \r
118             if(++pos >= args.length){\r
119                 System.err.println(\r
120                         "オプション " + arg + " に引数がありません。");\r
121                 System.exit(1);\r
122                 return;\r
123             }\r
124 \r
125             String val = args[pos];\r
126             if(arg.equals("-land")){\r
127                 landDef = getLandDef(val);\r
128                 if(landDef == null){\r
129                     System.err.println("不正な国識別子です。 " + val);\r
130                     System.exit(1);\r
131                     return;\r
132                 }\r
133             }else if(arg.equals("-vid")){\r
134                 vid = Integer.parseInt(val);\r
135                 if(vid < 0){\r
136                     System.err.println("不正な村番号です。 " + vid);\r
137                     System.exit(1);\r
138                     return;\r
139                 }\r
140             }else if(arg.equals("-outdir")){\r
141                 outdir = val;\r
142                 stdout = false;\r
143             }else{\r
144                 System.err.println("不正なオプションです。 " + arg);\r
145                 System.exit(1);\r
146                 return;\r
147             }\r
148         }\r
149 \r
150         if(landDef == null){\r
151             System.err.println(\r
152                     "-land オプションで国識別子を指定してください。");\r
153             System.exit(1);\r
154             return;\r
155         }\r
156 \r
157         if(vid < 0){\r
158             System.err.println(\r
159                     "-vid オプションで村番号を指定してください。");\r
160             System.exit(1);\r
161             return;\r
162         }\r
163 \r
164         if(   (outdir == null && stdout == false)\r
165            || (outdir != null && stdout == true)  ){\r
166             System.err.println(\r
167                     "-outdir か -stdout のどちらか一方を指定してください。");\r
168             System.exit(1);\r
169             return;\r
170         }\r
171 \r
172         Writer writer;\r
173         if(outdir != null){\r
174             writer = getFileWriter(outdir, landDef, vid);\r
175         }else{\r
176             writer = getStdOutWriter();\r
177         }\r
178 \r
179         writer = ValidateTask.wrapValidator(writer);\r
180 \r
181         try{\r
182             dump(writer, landDef, vid);\r
183         }catch(RuntimeException e){\r
184             throw e;\r
185         }catch(Exception e){\r
186             e.printStackTrace(System.err);\r
187             System.err.println("処理を続行できません。");\r
188             System.exit(1);\r
189             return;\r
190         }\r
191 \r
192         return;\r
193     }\r
194 \r
195     /**\r
196      * 主処理。人狼サーバからXHTMLを読み込み。XMLで出力。\r
197      * @param writer 出力先\r
198      * @param landDef 国情報\r
199      * @param vid 村番号\r
200      * @throws IOException 入出力エラー\r
201      * @throws DecodeException デコードエラー\r
202      * @throws HtmlParseException パースエラー\r
203      */\r
204     public static void dump(Writer writer, LandDef landDef, int vid)\r
205             throws IOException, DecodeException, HtmlParseException{\r
206         List<PeriodResource> resourceList =\r
207                 HttpAccess.loadResourceList(landDef, vid);\r
208         VillageData village = new VillageData(resourceList);\r
209 \r
210         Builder.fillVillageData(village);\r
211         XmlUtils.dumpVillageData(writer, village);\r
212 \r
213         return;\r
214     }\r
215 \r
216     /**\r
217      * 標準出力への出力先を得る。\r
218      * @return 出力先\r
219      */\r
220     public static Writer getStdOutWriter(){\r
221         OutputStream ostream;\r
222         ostream = new BufferedOutputStream(System.out);\r
223         Writer writer;\r
224         try{\r
225             writer = new OutputStreamWriter(ostream, "UTF-8");\r
226             writer = new BufferedWriter(writer, 4 * 1024);\r
227         }catch(IOException e){\r
228             System.err.println(\r
229                     "標準出力に書き込めません。");\r
230             System.exit(1);\r
231             return null;\r
232         }\r
233         return writer;\r
234     }\r
235 \r
236     /**\r
237      * ローカルファイルへの出力先を得る。\r
238      * @param outdir 出力ディレクトリ\r
239      * @param landDef 国情報\r
240      * @param vid 村番号\r
241      * @return 出力先\r
242      */\r
243     public static Writer getFileWriter(String outdir,\r
244                                          LandDef landDef,\r
245                                          int vid ){\r
246             File outFile = new File(outdir);\r
247             if( ! outFile.exists() ){\r
248                 System.err.println(\r
249                         outdir + " が存在しません。");\r
250                 System.exit(1);\r
251                 return null;\r
252             }\r
253             if( ! outFile.isDirectory() ){\r
254                 System.err.println(\r
255                         outdir + " はディレクトリではありません。");\r
256                 System.exit(1);\r
257                 return null;\r
258             }\r
259             if( ! outFile.canWrite() ){\r
260                 System.err.println(\r
261                         outdir + " に書き込めません。");\r
262                 System.exit(1);\r
263                 return null;\r
264             }\r
265             String fname = MessageFormat.format(\r
266                 "jin_{0}_{1,number,#00000}.xml", landDef.getLandId(), vid);\r
267             File xmlFile = new File(outFile, fname);\r
268             boolean created;\r
269             try{\r
270                 created = xmlFile.createNewFile();\r
271             }catch(IOException e){\r
272                 System.err.println(\r
273                         xmlFile.getName() + " が作成できません。");\r
274                 System.exit(1);\r
275                 return null;\r
276             }\r
277             if( ! created ){\r
278                 System.err.println(\r
279                         fname + " が既に" + outdir + "に存在します。");\r
280                 System.exit(1);\r
281                 return null;\r
282             }\r
283             /* JRE 1.6 only\r
284             xmlFile.setReadable(true);\r
285             xmlFile.setWritable(true);\r
286             xmlFile.setExecutable(false, false);\r
287             */\r
288             Writer writer;\r
289             try{\r
290                 OutputStream ostream;\r
291                 ostream = new FileOutputStream(xmlFile);\r
292                 ostream = new BufferedOutputStream(ostream, 4 * 1024);\r
293                 writer = new OutputStreamWriter(ostream, "UTF-8");\r
294                 writer = new BufferedWriter(writer, 4 * 1024);\r
295             }catch(IOException e){\r
296                 System.err.println(\r
297                         xmlFile.getName() + " に書き込めません。");\r
298                 System.exit(1);\r
299                 return null;\r
300             }\r
301 \r
302             return writer;\r
303     }\r
304 \r
305     /**\r
306      * スタートアップエントリ。\r
307      * @param args 引数\r
308      */\r
309     public static void main(String[] args){\r
310         parseOption(args);\r
311         System.exit(0);\r
312         return;\r
313     }\r
314 \r
315     /**\r
316      * 隠しコンストラクタ。\r
317      */\r
318     private JinArchiver(){\r
319         throw new Error();\r
320     }\r
321 \r
322 }\r