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.parser.MmdSource;
25 import jp.sourceforge.mikutoga.vmd.IllegalVmdDataException;
26 import jp.sourceforge.mikutoga.vmd.model.VmdMotion;
27 import jp.sourceforge.mikutoga.vmd.model.binio.VmdExporter;
28 import jp.sourceforge.mikutoga.vmd.model.binio.VmdLoader;
29 import jp.sourceforge.mikutoga.vmd.model.xml.VmdXmlExporter;
30 import jp.sourceforge.mikutoga.vmd.model.xml.VmdXmlResources;
31 import jp.sourceforge.mikutoga.vmd.model.xml.Xml2VmdLoader;
32 import jp.sourceforge.mikutoga.xml.TogaXmlException;
33 import org.xml.sax.InputSource;
34 import org.xml.sax.SAXException;
35 import org.xml.sax.SAXParseException;
39 * VMDモーションファイルとXMLとの間で変換を行うアプリケーション。
41 public final class Vmd2Xml {
43 private static final Class<?> THISCLASS;
44 private static final String APPNAME;
45 private static final String APPVER;
46 private static final String APPLICENSE;
47 private static final String APPURL;
49 private static final int EXIT_OK = 0;
50 private static final int EXIT_IOERR = 1;
51 private static final int EXIT_ENVERR = 4;
52 private static final int EXIT_OPTERR = 5;
53 private static final int EXIT_INTERR = 6;
54 private static final int EXIT_VMDERR = 7;
55 private static final int EXIT_XMLERR = 8;
57 private static final String ERRMSG_TXTONLY =
59 private static final String ERRMSG_SAXPARSE =
60 "ERROR : {0}\nline={1}, columun={2}\n";
63 THISCLASS = Vmd2Xml.class;
65 THISCLASS.getResourceAsStream("resources/version.properties");
66 Properties verProps = new Properties();
69 verProps.load(verDef);
73 }catch(IOException e){
74 throw new ExceptionInInitializerError(e);
77 APPNAME = verProps.getProperty("app.name");
78 APPVER = verProps.getProperty("app.version");
79 APPLICENSE = verProps.getProperty("app.license");
80 APPURL = verProps.getProperty("app.url");
82 new Vmd2Xml().hashCode();
91 assert this.getClass().equals(THISCLASS);
98 * @param args コマンドパラメータ
100 public static void main(String[] args){
103 ArgInfo argInfo = ArgInfo.buildArgInfo(args);
104 if(argInfo.hasOptionError()){
105 String message = argInfo.getErrorMessage() + "\n"
107 errExit(EXIT_OPTERR, message);
110 if(argInfo.isHelpMode()){
117 String input = argInfo.getInputFile();
118 String output = argInfo.getOutputFile();
120 InputStream is = null;
121 OutputStream os = null;
123 is = openInputStream(input);
124 os = openTruncatedOutputStream(output);
125 }catch(FileNotFoundException e){
127 }catch(IOException e){
131 if(argInfo.isVmd2XmlMode()) vmd2xml(is, os, argInfo);
132 else xml2vmd(is, os);
143 private static void checkJRE(){
144 Package jrePackage = java.lang.Object.class.getPackage();
145 if( ! jrePackage.isCompatibleWith("1.6")){
146 errExit(EXIT_ENVERR, "You need JRE 1.6 or later.\n");
154 private static void putHelp(){
155 StringBuilder text = new StringBuilder();
157 text.append(APPNAME).append(' ').append(APPVER).append('\n');
158 text.append(" License : ").append(APPLICENSE).append('\n');
159 text.append(" ").append(APPURL).append('\n');
161 text.append(ArgInfo.CMD_HELP);
169 * ファイルの各種状態を事前にチェックする。
170 * @param argInfo コマンドライン引数
172 private static void checkFiles(ArgInfo argInfo){
173 String input = argInfo.getInputFile();
174 String output = argInfo.getOutputFile();
175 File iFile = new File(input);
176 File oFile = new File(output);
178 if( ! FileUtils.isExistsNormalFile(iFile) ){
179 errExit(EXIT_IOERR, "Can't find input file:"
180 + iFile.getAbsolutePath() + '\n');
183 if(argInfo.isForceMode()){
184 if(FileUtils.isExistsUnnormalFile(oFile)){
185 errExit(EXIT_IOERR, oFile.getAbsolutePath()
186 + " is not file.\n");
188 }else if(oFile.exists()){
189 errExit(EXIT_IOERR, oFile.getAbsolutePath()
190 + " already exists.\n"
191 + "If you want to overwrite, use -f.\n");
199 * @param istream 入力ストリーム
200 * @param ostream 出力ストリーム
201 * @param argInfo オプション設定
203 private static void vmd2xml(InputStream istream, OutputStream ostream,
206 vmd2xmlImpl(istream, ostream, argInfo);
207 }catch(IOException e){
209 }catch(MmdFormatException e){
211 }catch(IllegalVmdDataException e){
220 * @param istream 入力ストリーム
221 * @param ostream 出力ストリーム
222 * @param argInfo オプション設定
223 * @throws IOException 入出力エラー
224 * @throws MmdFormatException 不正なVMDファイル
225 * @throws IllegalVmdDataException 不正なモーションデータ
227 private static void vmd2xmlImpl(InputStream istream, OutputStream ostream,
229 throws IOException, MmdFormatException, IllegalVmdDataException{
232 motion = vmdRead(istream);
240 xmlOut(motion, ostream, argInfo);
250 * @param istream 入力ストリーム
251 * @param ostream 出力ストリーム
253 private static void xml2vmd(InputStream istream, OutputStream ostream){
255 xml2vmdImpl(istream, ostream);
256 }catch(IOException e){
258 }catch(SAXException e){
260 }catch(TogaXmlException e){
262 }catch(IllegalVmdDataException e){
271 * @param istream 入力ストリーム
272 * @param ostream 出力ストリーム
273 * @throws IOException 入出力エラー
274 * @throws SAXException 不正なXMLファイル
275 * @throws TogaXmlException 不正なXMLファイル
276 * @throws IllegalVmdDataException 不正なVMDモーションデータ
278 private static void xml2vmdImpl(InputStream istream, OutputStream ostream)
282 IllegalVmdDataException {
283 InputSource source = new InputSource(istream);
286 motion = xmlRead(source);
294 vmdOut(motion, ostream);
303 * VMDファイルからモーションデータを読み込む。
306 * @throws IOException 入力エラー
307 * @throws MmdFormatException 不正なVMDファイルフォーマット
309 private static VmdMotion vmdRead(InputStream is)
310 throws IOException, MmdFormatException{
311 MmdSource source = new MmdSource(is);
312 VmdMotion vmdMotion = VmdLoader.load(source);
317 * モーションデータをXMLファイルに出力する。
318 * @param motion モーションデータ
319 * @param ostream 出力ストリーム
320 * @param argInfo オプション設定
321 * @throws IOException 出力エラー
322 * @throws IllegalVmdDataException 不正なモーションデータ
324 private static void xmlOut(VmdMotion motion, OutputStream ostream,
326 throws IOException, IllegalVmdDataException{
327 VmdXmlExporter exporter = new VmdXmlExporter(ostream);
329 exporter.setNewLine("\r\n");
330 exporter.setGenerator(APPNAME + ' ' + APPVER);
332 boolean isQuaternionMode = argInfo.isQuaternionMode();
333 exporter.setQuaternionMode(isQuaternionMode);
335 exporter.putVmdXml(motion);
342 * XMLファイルからモーションデータを読み込む。
343 * @param source 入力ソース
345 * @throws IOException 入力エラー
346 * @throws SAXException XML構文エラー
347 * @throws TogaXmlException 不正なXMLデータ
349 private static VmdMotion xmlRead(InputSource source)
353 DocumentBuilder builder =
354 VmdXmlResources.newBuilder(ValidationHandler.HANDLER);
355 Xml2VmdLoader loader = new Xml2VmdLoader(builder);
357 VmdMotion motion = loader.parse(source);
363 * モーションデータをVMDファイルに出力する。
364 * @param motion モーションデータ
365 * @param ostream 出力ストリーム
366 * @throws IOException 出力エラー
367 * @throws IllegalVmdDataException 不正なモーションデータ
369 private static void vmdOut(VmdMotion motion, OutputStream ostream)
370 throws IOException, IllegalVmdDataException{
371 VmdExporter exporter = new VmdExporter(ostream);
372 exporter.dumpVmdMotion(motion);
379 * @param fileName 入力ファイル名
381 * @throws FileNotFoundException 入力ファイルが見つからない。
383 private static InputStream openInputStream(String fileName)
384 throws FileNotFoundException {
385 File file = new File(fileName);
386 InputStream result = new FileInputStream(file);
387 result = new BufferedInputStream(result);
393 * @param fileName 出力ファイル名
395 * @throws FileNotFoundException 出力ファイルが見つからない
396 * @throws IOException 出力エラー
398 private static OutputStream openTruncatedOutputStream(String fileName)
399 throws FileNotFoundException, IOException {
400 File file = new File(fileName);
401 FileUtils.trunc(file);
402 OutputStream result = new FileOutputStream(file, false);
403 result = new BufferedOutputStream(result);
412 private static void ioError(IOException ex){
425 private static void internalError(Throwable ex){
428 ex.printStackTrace(System.err);
435 * VMDファイルフォーマットエラー処理。
439 private static void vmdError(MmdFormatException ex){
442 ex.printStackTrace(System.err);
453 private static void xmlError(SAXException ex){
454 if(ex instanceof SAXParseException){
455 xmlError((SAXParseException)ex);
458 String txt = ex.getLocalizedMessage();
459 String message = MessageFormat.format(ERRMSG_TXTONLY, txt);
472 private static void xmlError(SAXParseException ex){
473 String txt = ex.getLocalizedMessage();
474 int line = ex.getLineNumber();
475 int col = ex.getColumnNumber();
478 MessageFormat.format(ERRMSG_SAXPARSE, txt, line, col);
491 private static void xmlError(TogaXmlException ex){
492 String txt = ex.getLocalizedMessage();
493 String message = MessageFormat.format(ERRMSG_TXTONLY, txt);
505 private static void exit(int code){
508 throw new AssertionError();
515 @SuppressWarnings("PMD.SystemPrintln")
516 private static void errprint(Object obj){
517 System.err.print(obj.toString());
526 private static void errExit(int code, CharSequence text){
527 errprint("ERROR:\n");