2 * command line argument info
4 * License : The MIT License
5 * Copyright(c) 2013 MikuToga Partners
8 package jp.sfjp.mikutoga.vmd2xml;
10 import java.text.MessageFormat;
11 import java.util.List;
12 import java.util.Locale;
19 private static final String EOL_LF = "\n";
20 private static final String EOL_CRLF = "\r\n";
21 private static final String EOL_DEFAULT = EOL_LF;
23 private static final String FORMAT_VMD = "vmd";
24 private static final String FORMAT_XML = "xml";
25 private static final String FORMAT_XML110820 = "xml110820";
26 private static final String FORMAT_XML130609 = "xml130609";
28 private static final String SFX_VMD = ".vmd";
29 private static final String SFX_XML = ".xml";
31 private static final String NL_LF = "lf";
32 private static final String NL_CRLF = "crlf";
34 private static final String ERRMSG_UNKNOWN =
35 "Unknown option : {0}";
36 private static final String ERRMSG_MOREARG =
37 "You need option arg with : {0}";
38 private static final String ERRMSG_INTYPE =
39 "You must specify input format with -iform.";
40 private static final String ERRMSG_OUTTYPE =
41 "You must specify output format with -oform.";
42 private static final String ERRMSG_NOINFILE =
43 "You must specify input file with -i.";
44 private static final String ERRMSG_NOOUTFILE =
45 "You must specify output file with -o.";
46 private static final String ERRMSG_INVFORM =
47 "Unknown format : \"{0}\" must be \"vmd\" or \"xml\" "
49 private static final String ERRMSG_INVNL =
50 "Unknown newline : \"{0}\" must be \"lf\" or \"crlf\"";
51 private static final String ERRMSG_INVBOOL =
52 "Unknown switch : \"{0}\" must be \"on\" or \"off\"";
55 private boolean needHelp = false;
56 private MotionFileType inTypes = MotionFileType.NONE;
57 private MotionFileType outTypes = MotionFileType.NONE;
58 private String inFilename = null;
59 private String outFilename = null;
60 private boolean overwrite = false;
61 private String newline = EOL_DEFAULT;
62 private String generator = Vmd2Xml.GENERATOR;
63 private boolean isQuaternionMode = true;
79 * @throws CmdLineException 不正なフォーマット種別
81 private static MotionFileType decodeFormatType(String arg)
82 throws CmdLineException{
83 MotionFileType result;
85 if (FORMAT_VMD.equals(arg)){
86 result = MotionFileType.VMD;
87 }else if(FORMAT_XML.equals(arg)){
88 result = MotionFileType.XML_AUTO;
89 }else if(FORMAT_XML110820.equals(arg)){
90 result = MotionFileType.XML_110820;
91 }else if(FORMAT_XML130609.equals(arg)){
92 result = MotionFileType.XML_130609;
94 String errMsg = MessageFormat.format(ERRMSG_INVFORM, arg);
95 throw new CmdLineException(errMsg);
105 * @throws CmdLineException 不正なフォーマット種別
107 private static String decodeNewline(String arg)
108 throws CmdLineException{
111 if (NL_LF.equals(arg)){
113 }else if(NL_CRLF.equals(arg)){
116 String errMsg = MessageFormat.format(ERRMSG_INVNL, arg);
117 throw new CmdLineException(errMsg);
127 * @throws CmdLineException 不正なフォーマット種別
129 private static boolean decodeBoolean(String arg)
130 throws CmdLineException{
133 if( "on" .equals(arg)
134 || "true".equals(arg)
135 || "yes" .equals(arg) ){
137 }else if( "off" .equals(arg)
138 || "false".equals(arg)
139 || "no" .equals(arg) ){
142 String errMsg = MessageFormat.format(ERRMSG_INVBOOL, arg);
143 throw new CmdLineException(errMsg);
150 * ファイル名からファイル種別を類推する。
151 * <p>拡張子が「.vmd」ならVMDファイル、「.xml」ならXMLファイル。
152 * @param fileName ファイル名
153 * @return ファイル種別。識別不可ならNONE。
155 private static MotionFileType getFileType(String fileName){
156 MotionFileType result = MotionFileType.NONE;
157 if(fileName == null) return result;
159 String lower = fileName.toLowerCase(Locale.ROOT);
160 if (lower.endsWith(SFX_VMD)) result = MotionFileType.VMD;
161 else if(lower.endsWith(SFX_XML)) result = MotionFileType.XML_AUTO;
167 * ヘルプ要求があるかコマンドライン列を調べる。
168 * @param cmds コマンドライン列
169 * @return ヘルプ要求があればtrue
171 private static boolean hasHelp(List<CmdLine> cmds){
172 for(CmdLine cmd : cmds){
173 OptSwitch opt = cmd.getOptSwitch();
174 if(opt == OptSwitch.OPT_HELP){
183 * @param opt オプション識別子
184 * @param exArg 引数。なければnull
185 * @param result オプション情報格納先
186 * @throws CmdLineException 不正なコマンドライン
188 private static void storeOptInfo(OptSwitch opt,
191 throws CmdLineException{
194 result.overwrite = true;
197 result.isQuaternionMode = true;
200 result.isQuaternionMode = false;
203 result.inFilename = exArg;
206 result.outFilename = exArg;
209 result.newline = decodeNewline(exArg);
212 MotionFileType itype = decodeFormatType(exArg);
213 result.inTypes = itype;
216 MotionFileType otype = decodeFormatType(exArg);
217 result.outTypes = otype;
220 boolean genout = decodeBoolean(exArg);
221 if(genout) result.generator = Vmd2Xml.GENERATOR;
222 else result.generator = null;
233 * @param args コマンドライン
235 * @throws CmdLineException 不正なコマンドライン
237 static OptInfo parseOption(String... args) throws CmdLineException{
238 List<CmdLine> cmdLines = CmdLine.parse(args);
240 OptInfo result = new OptInfo();
242 if(hasHelp(cmdLines)){
243 result.needHelp = true;
247 checkCmdLineList(cmdLines);
249 for(CmdLine cmd : cmdLines){
250 OptSwitch opt = cmd.getOptSwitch();
252 List<String> optArgs = cmd.getOptArgs();
253 String exArg1 = null;
254 if(optArgs.size() >= 2){
255 exArg1 = optArgs.get(1);
258 storeOptInfo(opt, exArg1, result);
269 * 単純なコマンドラインエラーを検出する。
270 * <p>検出項目は未知のオプションおよび不正な引数の個数
271 * @param cmdLines コマンドライン
272 * @throws CmdLineException 異常系
274 private static void checkCmdLineList(List<CmdLine> cmdLines)
275 throws CmdLineException{
276 for(CmdLine cmd : cmdLines){
277 List<String> optArgs = cmd.getOptArgs();
278 assert ! optArgs.isEmpty();
280 String optTxt = optArgs.get(0);
281 assert optTxt != null;
283 OptSwitch opt = cmd.getOptSwitch();
286 MessageFormat.format(ERRMSG_UNKNOWN, optTxt);
287 throw new CmdLineException(errMsg);
290 int exArgNum = opt.getExArgNum();
291 if(optArgs.size() != 1 + exArgNum){
293 MessageFormat.format(ERRMSG_MOREARG, optTxt);
294 throw new CmdLineException(errMsg);
302 * ファイルフォーマット情報の推測を行う。
303 * @param result オプション情報
305 private static void fixFormat(OptInfo result){
306 if(result.inTypes == MotionFileType.NONE){
307 result.inTypes = getFileType(result.inFilename);
310 if(result.outTypes == MotionFileType.NONE){
311 result.outTypes = getFileType(result.outFilename);
319 * @param result オプション情報
320 * @throws CmdLineException 不正なオプション設定
322 private static void checkResult(OptInfo result)
323 throws CmdLineException{
324 if(result.getInFilename() == null){
325 throw new CmdLineException(ERRMSG_NOINFILE);
328 if(result.getOutFilename() == null){
329 throw new CmdLineException(ERRMSG_NOOUTFILE);
332 if(result.getInFileType() == MotionFileType.NONE){
333 throw new CmdLineException(ERRMSG_INTYPE);
336 if(result.getOutFileType() == MotionFileType.NONE){
337 throw new CmdLineException(ERRMSG_OUTTYPE);
349 return this.needHelp;
356 MotionFileType getInFileType(){
364 MotionFileType getOutFileType(){
365 return this.outTypes;
372 String getInFilename(){
373 return this.inFilename;
380 String getOutFilename(){
381 return this.outFilename;
386 * @return 上書きモードならtrue
388 boolean overwriteMode(){
389 return this.overwrite;
402 * @return ジェネレータ名。表示したくない時はnull
404 String getGenerator(){
405 return this.generator;
410 * @return クォータニオン形式ならtrue、YXZオイラー角形式ならfalse。
412 boolean isQuaterniomMode(){
413 return this.isQuaternionMode;