2 * vmd to xml converter main entry
4 * License : The MIT License
5 * Copyright(c) 2011 MikuToga Partners
8 package jp.sourceforge.mikutoga.vmd2xml;
10 import java.io.BufferedInputStream;
11 import java.io.BufferedOutputStream;
13 import java.io.FileInputStream;
14 import java.io.FileNotFoundException;
15 import java.io.FileOutputStream;
16 import java.io.IOException;
17 import java.io.InputStream;
18 import java.io.OutputStream;
19 import java.text.MessageFormat;
20 import java.util.Properties;
21 import javax.xml.parsers.DocumentBuilder;
22 import jp.sourceforge.mikutoga.binio.FileUtils;
23 import jp.sourceforge.mikutoga.parser.MmdFormatException;
24 import jp.sourceforge.mikutoga.vmd.IllegalVmdDataException;
25 import jp.sourceforge.mikutoga.vmd.model.VmdMotion;
26 import jp.sourceforge.mikutoga.vmd.model.binio.VmdExporter;
27 import jp.sourceforge.mikutoga.vmd.model.binio.VmdLoader;
28 import jp.sourceforge.mikutoga.vmd.model.xml.VmdXmlExporter;
29 import jp.sourceforge.mikutoga.vmd.model.xml.VmdXmlResources;
30 import jp.sourceforge.mikutoga.vmd.model.xml.Xml2VmdLoader;
31 import jp.sourceforge.mikutoga.xml.TogaXmlException;
32 import org.xml.sax.InputSource;
33 import org.xml.sax.SAXException;
34 import org.xml.sax.SAXParseException;
38 * VMDモーションファイルとXMLとの間で変換を行うアプリケーション。
40 public final class Vmd2Xml {
42 private static final Class<?> THISCLASS;
43 private static final String APPNAME;
44 private static final String APPVER;
45 private static final String APPLICENSE;
46 private static final String APPURL;
48 private static final int EXIT_OK = 0;
49 private static final int EXIT_IOERR = 1;
50 private static final int EXIT_ENVERR = 4;
51 private static final int EXIT_OPTERR = 5;
52 private static final int EXIT_INTERR = 6;
53 private static final int EXIT_VMDERR = 7;
54 private static final int EXIT_XMLERR = 8;
56 private static final String ERRMSG_TXTONLY =
58 private static final String ERRMSG_SAXPARSE =
59 "ERROR : {0}\nline={1}, columun={2}\n";
62 THISCLASS = Vmd2Xml.class;
64 THISCLASS.getResourceAsStream("resources/version.properties");
65 Properties verProps = new Properties();
68 verProps.load(verDef);
72 }catch(IOException e){
73 throw new ExceptionInInitializerError(e);
76 APPNAME = verProps.getProperty("app.name");
77 APPVER = verProps.getProperty("app.version");
78 APPLICENSE = verProps.getProperty("app.license");
79 APPURL = verProps.getProperty("app.url");
81 new Vmd2Xml().hashCode();
90 assert this.getClass().equals(THISCLASS);
97 * @param args コマンドパラメータ
99 public static void main(String[] args){
102 ArgInfo argInfo = ArgInfo.buildArgInfo(args);
103 if(argInfo.hasOptionError()){
104 String message = argInfo.getErrorMessage() + "\n"
106 errExit(EXIT_OPTERR, message);
109 if(argInfo.isHelpMode()){
116 String input = argInfo.getInputFile();
117 String output = argInfo.getOutputFile();
119 InputStream is = null;
120 OutputStream os = null;
122 is = openInputStream(input);
123 os = openTruncatedOutputStream(output);
124 }catch(FileNotFoundException e){
126 }catch(IOException e){
130 if(argInfo.isVmd2XmlMode()) vmd2xml(is, os, argInfo);
131 else xml2vmd(is, os);
142 private static void checkJRE(){
143 Package jrePackage = java.lang.Object.class.getPackage();
144 if( ! jrePackage.isCompatibleWith("1.6")){
145 errExit(EXIT_ENVERR, "You need JRE 1.6 or later.\n");
153 private static void putHelp(){
154 StringBuilder text = new StringBuilder();
156 text.append(APPNAME).append(' ').append(APPVER).append('\n');
157 text.append(" License : ").append(APPLICENSE).append('\n');
158 text.append(" ").append(APPURL).append('\n');
160 text.append(ArgInfo.CMD_HELP);
168 * ファイルの各種状態を事前にチェックする。
169 * @param argInfo コマンドライン引数
171 private static void checkFiles(ArgInfo argInfo){
172 String input = argInfo.getInputFile();
173 String output = argInfo.getOutputFile();
174 File iFile = new File(input);
175 File oFile = new File(output);
177 if( ! FileUtils.isExistsNormalFile(iFile) ){
178 errExit(EXIT_IOERR, "Can't find input file:"
179 + iFile.getAbsolutePath() + '\n');
182 if(argInfo.isForceMode()){
183 if(FileUtils.isExistsUnnormalFile(oFile)){
184 errExit(EXIT_IOERR, oFile.getAbsolutePath()
185 + " is not file.\n");
187 }else if(oFile.exists()){
188 errExit(EXIT_IOERR, oFile.getAbsolutePath()
189 + " already exists.\n"
190 + "If you want to overwrite, use -f.\n");
198 * @param istream 入力ストリーム
199 * @param ostream 出力ストリーム
200 * @param argInfo オプション設定
202 private static void vmd2xml(InputStream istream, OutputStream ostream,
205 vmd2xmlImpl(istream, ostream, argInfo);
206 }catch(IOException e){
208 }catch(MmdFormatException e){
210 }catch(IllegalVmdDataException e){
219 * @param istream 入力ストリーム
220 * @param ostream 出力ストリーム
221 * @param argInfo オプション設定
222 * @throws IOException 入出力エラー
223 * @throws MmdFormatException 不正なVMDファイル
224 * @throws IllegalVmdDataException 不正なモーションデータ
226 private static void vmd2xmlImpl(InputStream istream, OutputStream ostream,
228 throws IOException, MmdFormatException, IllegalVmdDataException{
231 motion = vmdRead(istream);
239 xmlOut(motion, ostream, argInfo);
249 * @param istream 入力ストリーム
250 * @param ostream 出力ストリーム
252 private static void xml2vmd(InputStream istream, OutputStream ostream){
254 xml2vmdImpl(istream, ostream);
255 }catch(IOException e){
257 }catch(SAXException e){
259 }catch(TogaXmlException e){
261 }catch(IllegalVmdDataException e){
270 * @param istream 入力ストリーム
271 * @param ostream 出力ストリーム
272 * @throws IOException 入出力エラー
273 * @throws SAXException 不正なXMLファイル
274 * @throws TogaXmlException 不正なXMLファイル
275 * @throws IllegalVmdDataException 不正なVMDモーションデータ
277 private static void xml2vmdImpl(InputStream istream, OutputStream ostream)
281 IllegalVmdDataException {
282 InputSource source = new InputSource(istream);
285 motion = xmlRead(source);
293 vmdOut(motion, ostream);
302 * VMDファイルからモーションデータを読み込む。
305 * @throws IOException 入力エラー
306 * @throws MmdFormatException 不正なVMDファイルフォーマット
308 private static VmdMotion vmdRead(InputStream is)
309 throws IOException, MmdFormatException{
310 VmdMotion vmdMotion = VmdLoader.load(is);
315 * モーションデータをXMLファイルに出力する。
316 * @param motion モーションデータ
317 * @param ostream 出力ストリーム
318 * @param argInfo オプション設定
319 * @throws IOException 出力エラー
320 * @throws IllegalVmdDataException 不正なモーションデータ
322 private static void xmlOut(VmdMotion motion, OutputStream ostream,
324 throws IOException, IllegalVmdDataException{
325 VmdXmlExporter exporter = new VmdXmlExporter(ostream);
327 exporter.setNewLine("\r\n");
328 exporter.setGenerator(APPNAME + ' ' + APPVER);
330 boolean isQuaternionMode = argInfo.isQuaternionMode();
331 exporter.setQuaternionMode(isQuaternionMode);
333 exporter.putVmdXml(motion);
340 * XMLファイルからモーションデータを読み込む。
341 * @param source 入力ソース
343 * @throws IOException 入力エラー
344 * @throws SAXException XML構文エラー
345 * @throws TogaXmlException 不正なXMLデータ
347 private static VmdMotion xmlRead(InputSource source)
351 DocumentBuilder builder =
352 VmdXmlResources.newBuilder(ValidationHandler.HANDLER);
353 Xml2VmdLoader loader = new Xml2VmdLoader(builder);
355 VmdMotion motion = loader.parse(source);
361 * モーションデータをVMDファイルに出力する。
362 * @param motion モーションデータ
363 * @param ostream 出力ストリーム
364 * @throws IOException 出力エラー
365 * @throws IllegalVmdDataException 不正なモーションデータ
367 private static void vmdOut(VmdMotion motion, OutputStream ostream)
368 throws IOException, IllegalVmdDataException{
369 VmdExporter exporter = new VmdExporter(ostream);
370 exporter.dumpVmdMotion(motion);
377 * @param fileName 入力ファイル名
379 * @throws FileNotFoundException 入力ファイルが見つからない。
381 private static InputStream openInputStream(String fileName)
382 throws FileNotFoundException {
383 File file = new File(fileName);
384 InputStream result = new FileInputStream(file);
385 result = new BufferedInputStream(result);
391 * @param fileName 出力ファイル名
393 * @throws FileNotFoundException 出力ファイルが見つからない
394 * @throws IOException 出力エラー
396 private static OutputStream openTruncatedOutputStream(String fileName)
397 throws FileNotFoundException, IOException {
398 File file = new File(fileName);
399 FileUtils.trunc(file);
400 OutputStream result = new FileOutputStream(file, false);
401 result = new BufferedOutputStream(result);
410 private static void ioError(IOException ex){
423 private static void internalError(Throwable ex){
426 ex.printStackTrace(System.err);
433 * VMDファイルフォーマットエラー処理。
437 private static void vmdError(MmdFormatException ex){
440 ex.printStackTrace(System.err);
451 private static void xmlError(SAXException ex){
452 if(ex instanceof SAXParseException){
453 xmlError((SAXParseException)ex);
456 String txt = ex.getLocalizedMessage();
457 String message = MessageFormat.format(ERRMSG_TXTONLY, txt);
470 private static void xmlError(SAXParseException ex){
471 String txt = ex.getLocalizedMessage();
472 int line = ex.getLineNumber();
473 int col = ex.getColumnNumber();
476 MessageFormat.format(ERRMSG_SAXPARSE, txt, line, col);
489 private static void xmlError(TogaXmlException ex){
490 String txt = ex.getLocalizedMessage();
491 String message = MessageFormat.format(ERRMSG_TXTONLY, txt);
503 private static void exit(int code){
506 throw new AssertionError();
513 @SuppressWarnings("PMD.SystemPrintln")
514 private static void errprint(Object obj){
515 System.err.print(obj.toString());
524 private static void errExit(int code, CharSequence text){
525 errprint("ERROR:\n");