--tag -> --search-tag
[fanfix.git] / src / be / nikiroo / fanfix / Main.java
1 package be.nikiroo.fanfix;
2
3 import java.io.File;
4 import java.io.IOException;
5 import java.net.MalformedURLException;
6 import java.net.URL;
7 import java.util.ArrayList;
8 import java.util.List;
9
10 import be.nikiroo.fanfix.bundles.StringId;
11 import be.nikiroo.fanfix.data.Chapter;
12 import be.nikiroo.fanfix.data.MetaData;
13 import be.nikiroo.fanfix.data.Story;
14 import be.nikiroo.fanfix.library.BasicLibrary;
15 import be.nikiroo.fanfix.library.CacheLibrary;
16 import be.nikiroo.fanfix.library.LocalLibrary;
17 import be.nikiroo.fanfix.library.RemoteLibrary;
18 import be.nikiroo.fanfix.library.RemoteLibraryServer;
19 import be.nikiroo.fanfix.output.BasicOutput;
20 import be.nikiroo.fanfix.output.BasicOutput.OutputType;
21 import be.nikiroo.fanfix.reader.BasicReader;
22 import be.nikiroo.fanfix.reader.Reader;
23 import be.nikiroo.fanfix.reader.Reader.ReaderType;
24 import be.nikiroo.fanfix.searchable.BasicSearchable;
25 import be.nikiroo.fanfix.supported.BasicSupport;
26 import be.nikiroo.fanfix.supported.SupportType;
27 import be.nikiroo.utils.Progress;
28 import be.nikiroo.utils.Version;
29 import be.nikiroo.utils.serial.server.ServerObject;
30
31 /**
32 * Main program entry point.
33 *
34 * @author niki
35 */
36 public class Main {
37 private enum MainAction {
38 IMPORT, EXPORT, CONVERT, READ, READ_URL, LIST, HELP, SET_READER, START, VERSION, SERVER, STOP_SERVER, REMOTE, SET_SOURCE, SET_TITLE, SET_AUTHOR, SEARCH, SEARCH_TAG
39 }
40
41 /**
42 * Main program entry point.
43 * <p>
44 * Known environment variables:
45 * <ul>
46 * <li>NOUTF: if set to 1 or 'true', the program will prefer non-unicode
47 * {@link String}s when possible</li>
48 * <li>CONFIG_DIR: a path where to look for the <tt>.properties</tt> files
49 * before taking the usual ones; they will also be saved/updated into this
50 * path when the program starts</li>
51 * <li>DEBUG: if set to 1 or 'true', the program will override the DEBUG_ERR
52 * configuration value with 'true'</li>
53 * </ul>
54 * <p>
55 * <ul>
56 * <li>--import [URL]: import into library</li>
57 * <li>--export [id] [output_type] [target]: export story to target</li>
58 * <li>--convert [URL] [output_type] [target] (+info): convert URL into
59 * target</li>
60 * <li>--read [id] ([chapter number]): read the given story from the library
61 * </li>
62 * <li>--read-url [URL] ([chapter number]): convert on the fly and read the
63 * story, without saving it</li>
64 * <li>--search: list the supported websites (where)</li>
65 * <li>--search [where] [keywords] (page [page]) (item [item]): search on
66 * the supported website and display the given results page of stories it
67 * found, or the story details if asked</li>
68 * <li>--search-tag [where]: list all the tags supported by this website</li>
69 * <li>--search-tag [index 1]... (page [page]) (item [item]): search for the
70 * given stories or subtags, tag by tag, and display information about a
71 * specific page of results or about a specific item if requested</li>
72 * <li>--list ([type]): list the stories present in the library</li>
73 * <li>--set-source [id] [new source]: change the source of the given story</li>
74 * <li>--set-title [id] [new title]: change the title of the given story</li>
75 * <li>--set-author [id] [new author]: change the author of the given story</li>
76 * <li>--set-reader [reader type]: set the reader type to CLI, TUI or LOCAL
77 * for this command</li>
78 * <li>--version: get the version of the program</li>
79 * <li>--server [key] [port]: start a server on this port</li>
80 * <li>--stop-server [key] [port]: stop the running server on this port if
81 * any</li>
82 * <li>--remote [key] [host] [port]: use a the given remote library</li>
83 * </ul>
84 *
85 * @param args
86 * see method description
87 */
88 public static void main(String[] args) {
89 String urlString = null;
90 String luid = null;
91 String sourceString = null;
92 String titleString = null;
93 String authorString = null;
94 String chapString = null;
95 String target = null;
96 String key = null;
97 MainAction action = MainAction.START;
98 Boolean plusInfo = null;
99 String host = null;
100 Integer port = null;
101 SupportType searchOn = null;
102 String search = null;
103 List<Integer> tags = new ArrayList<Integer>();
104 Integer page = null;
105 Integer item = null;
106
107 boolean noMoreActions = false;
108
109 int exitCode = 0;
110 for (int i = 0; exitCode == 0 && i < args.length; i++) {
111 // Action (--) handling:
112 if (!noMoreActions && args[i].startsWith("--")) {
113 if (args[i].equals("--")) {
114 noMoreActions = true;
115 } else {
116 try {
117 action = MainAction.valueOf(args[i].substring(2)
118 .toUpperCase().replace("-", "_"));
119 } catch (Exception e) {
120 Instance.getTraceHandler().error(
121 new IllegalArgumentException("Unknown action: "
122 + args[i], e));
123 exitCode = 255;
124 }
125 }
126
127 continue;
128 }
129
130 switch (action) {
131 case IMPORT:
132 if (urlString == null) {
133 urlString = args[i];
134 } else {
135 exitCode = 255;
136 }
137 break;
138 case EXPORT:
139 if (luid == null) {
140 luid = args[i];
141 } else if (sourceString == null) {
142 sourceString = args[i];
143 } else if (target == null) {
144 target = args[i];
145 } else {
146 exitCode = 255;
147 }
148 break;
149 case CONVERT:
150 if (urlString == null) {
151 urlString = args[i];
152 } else if (sourceString == null) {
153 sourceString = args[i];
154 } else if (target == null) {
155 target = args[i];
156 } else if (plusInfo == null) {
157 if ("+info".equals(args[i])) {
158 plusInfo = true;
159 } else {
160 exitCode = 255;
161 }
162 } else {
163 exitCode = 255;
164 }
165 break;
166 case LIST:
167 if (sourceString == null) {
168 sourceString = args[i];
169 } else {
170 exitCode = 255;
171 }
172 break;
173 case SET_SOURCE:
174 if (luid == null) {
175 luid = args[i];
176 } else if (sourceString == null) {
177 sourceString = args[i];
178 } else {
179 exitCode = 255;
180 }
181 break;
182 case SET_TITLE:
183 if (luid == null) {
184 luid = args[i];
185 } else if (sourceString == null) {
186 titleString = args[i];
187 } else {
188 exitCode = 255;
189 }
190 break;
191 case SET_AUTHOR:
192 if (luid == null) {
193 luid = args[i];
194 } else if (sourceString == null) {
195 authorString = args[i];
196 } else {
197 exitCode = 255;
198 }
199 break;
200 case READ:
201 if (luid == null) {
202 luid = args[i];
203 } else if (chapString == null) {
204 chapString = args[i];
205 } else {
206 exitCode = 255;
207 }
208 break;
209 case READ_URL:
210 if (urlString == null) {
211 urlString = args[i];
212 } else if (chapString == null) {
213 chapString = args[i];
214 } else {
215 exitCode = 255;
216 }
217 break;
218 case SEARCH:
219 if (searchOn == null) {
220 searchOn = SupportType.valueOfAllOkUC(args[i]);
221
222 if (searchOn == null) {
223 Instance.getTraceHandler().error(
224 "Website not known: <" + args[i] + ">");
225 exitCode = 41;
226 break;
227 }
228
229 if (BasicSearchable.getSearchable(searchOn) == null) {
230 Instance.getTraceHandler().error(
231 "Website not supported: " + searchOn);
232 exitCode = 42;
233 break;
234 }
235 } else if (search == null) {
236 search = args[i];
237 } else if (page != null && page == -1) {
238 try {
239 page = Integer.parseInt(args[i]);
240 } catch (Exception e) {
241 page = -2;
242 }
243 } else if (item != null && item == -1) {
244 try {
245 item = Integer.parseInt(args[i]);
246 } catch (Exception e) {
247 item = -2;
248 }
249 } else if (page == null || item == null) {
250 if (page == null && "page".equals(args[i])) {
251 page = -1;
252 } else if (item == null && "item".equals(args[i])) {
253 item = -1;
254 } else {
255 exitCode = 255;
256 }
257 } else {
258 exitCode = 255;
259 }
260 break;
261 case SEARCH_TAG:
262 if (searchOn == null) {
263 searchOn = SupportType.valueOfAllOkUC(args[i]);
264
265 if (searchOn == null) {
266 Instance.getTraceHandler().error(
267 "Website not known: <" + args[i] + ">");
268 exitCode = 255;
269 }
270
271 if (BasicSearchable.getSearchable(searchOn) == null) {
272 Instance.getTraceHandler().error(
273 "Website not supported: " + searchOn);
274 exitCode = 255;
275 }
276 } else if (page == null && item == null) {
277 if ("page".equals(args[i])) {
278 page = -1;
279 } else if ("item".equals(args[i])) {
280 item = -1;
281 } else {
282 try {
283 int index = Integer.parseInt(args[i]);
284 tags.add(index);
285 } catch (NumberFormatException e) {
286 Instance.getTraceHandler().error(
287 "Invalid tag index: " + args[i]);
288 exitCode = 255;
289 }
290 }
291 } else if (page != null && page == -1) {
292 try {
293 page = Integer.parseInt(args[i]);
294 } catch (Exception e) {
295 page = -2;
296 }
297 } else if (item != null && item == -1) {
298 try {
299 item = Integer.parseInt(args[i]);
300 } catch (Exception e) {
301 item = -2;
302 }
303 } else if (page == null || item == null) {
304 if (page == null && "page".equals(args[i])) {
305 page = -1;
306 } else if (item == null && "item".equals(args[i])) {
307 item = -1;
308 } else {
309 exitCode = 255;
310 }
311 } else {
312 exitCode = 255;
313 }
314 break;
315 case HELP:
316 exitCode = 255;
317 break;
318 case SET_READER:
319 exitCode = setReaderType(args[i]);
320 action = MainAction.START;
321 break;
322 case START:
323 exitCode = 255; // not supposed to be selected by user
324 break;
325 case VERSION:
326 exitCode = 255; // no arguments for this option
327 break;
328 case SERVER:
329 case STOP_SERVER:
330 if (key == null) {
331 key = args[i];
332 } else if (port == null) {
333 port = Integer.parseInt(args[i]);
334 } else {
335 exitCode = 255;
336 }
337 break;
338 case REMOTE:
339 if (key == null) {
340 key = args[i];
341 } else if (host == null) {
342 host = args[i];
343 } else if (port == null) {
344 port = Integer.parseInt(args[i]);
345
346 BasicLibrary lib = new RemoteLibrary(key, host, port);
347 lib = new CacheLibrary(Instance.getRemoteDir(host), lib);
348
349 BasicReader.setDefaultLibrary(lib);
350
351 action = MainAction.START;
352 } else {
353 exitCode = 255;
354 }
355 break;
356 }
357 }
358
359 final Progress mainProgress = new Progress(0, 80);
360 mainProgress.addProgressListener(new Progress.ProgressListener() {
361 private int current = mainProgress.getMin();
362
363 @Override
364 public void progress(Progress progress, String name) {
365 int diff = progress.getProgress() - current;
366 current += diff;
367
368 if (diff <= 0)
369 return;
370
371 StringBuilder builder = new StringBuilder();
372 for (int i = 0; i < diff; i++) {
373 builder.append('.');
374 }
375
376 System.err.print(builder.toString());
377
378 if (progress.isDone()) {
379 System.err.println("");
380 }
381 }
382 });
383 Progress pg = new Progress();
384 mainProgress.addProgress(pg, mainProgress.getMax());
385
386 VersionCheck updates = VersionCheck.check();
387 if (updates.isNewVersionAvailable()) {
388 // Sent to syserr so not to cause problem if one tries to capture a
389 // story content in text mode
390 System.err
391 .println("A new version of the program is available at https://github.com/nikiroo/fanfix/releases");
392 System.err.println("");
393 for (Version v : updates.getNewer()) {
394 System.err.println("\tVersion " + v);
395 System.err.println("\t-------------");
396 System.err.println("");
397 for (String it : updates.getChanges().get(v)) {
398 System.err.println("\t- " + it);
399 }
400 System.err.println("");
401 }
402 }
403
404 if (exitCode == 0) {
405 switch (action) {
406 case IMPORT:
407 exitCode = imprt(urlString, pg);
408 updates.ok(); // we consider it read
409 break;
410 case EXPORT:
411 exitCode = export(luid, sourceString, target, pg);
412 updates.ok(); // we consider it read
413 break;
414 case CONVERT:
415 exitCode = convert(urlString, sourceString, target,
416 plusInfo == null ? false : plusInfo, pg);
417 updates.ok(); // we consider it read
418 break;
419 case LIST:
420 if (BasicReader.getReader() == null) {
421 Instance.getTraceHandler()
422 .error(new Exception(
423 "No reader type has been configured"));
424 exitCode = 10;
425 break;
426 }
427 exitCode = list(sourceString);
428 break;
429 case SET_SOURCE:
430 try {
431 Instance.getLibrary().changeSource(luid, sourceString, pg);
432 } catch (IOException e1) {
433 Instance.getTraceHandler().error(e1);
434 exitCode = 21;
435 }
436 break;
437 case SET_TITLE:
438 try {
439 Instance.getLibrary().changeTitle(luid, titleString, pg);
440 } catch (IOException e1) {
441 Instance.getTraceHandler().error(e1);
442 exitCode = 22;
443 }
444 break;
445 case SET_AUTHOR:
446 try {
447 Instance.getLibrary().changeAuthor(luid, authorString, pg);
448 } catch (IOException e1) {
449 Instance.getTraceHandler().error(e1);
450 exitCode = 23;
451 }
452 break;
453 case READ:
454 if (BasicReader.getReader() == null) {
455 Instance.getTraceHandler()
456 .error(new Exception(
457 "No reader type has been configured"));
458 exitCode = 10;
459 break;
460 }
461 exitCode = read(luid, chapString, true);
462 break;
463 case READ_URL:
464 if (BasicReader.getReader() == null) {
465 Instance.getTraceHandler()
466 .error(new Exception(
467 "No reader type has been configured"));
468 exitCode = 10;
469 break;
470 }
471 exitCode = read(urlString, chapString, false);
472 break;
473 case SEARCH:
474 page = page == null ? 1 : page;
475 if (page < 0) {
476 Instance.getTraceHandler().error("Incorrect page number");
477 exitCode = 255;
478 break;
479 }
480
481 item = item == null ? 0 : item;
482 if (item < 0) {
483 Instance.getTraceHandler().error("Incorrect item number");
484 exitCode = 255;
485 break;
486 }
487
488 if (BasicReader.getReader() == null) {
489 Instance.getTraceHandler()
490 .error(new Exception(
491 "No reader type has been configured"));
492 exitCode = 10;
493 break;
494 }
495
496 try {
497 if (searchOn == null) {
498 BasicReader.getReader().search(true);
499 } else if (search != null) {
500
501 BasicReader.getReader().search(searchOn, search, page,
502 item, true);
503 } else {
504 exitCode = 255;
505 }
506 } catch (IOException e1) {
507 Instance.getTraceHandler().error(e1);
508 exitCode = 20;
509 }
510
511 break;
512 case SEARCH_TAG:
513 if (searchOn == null) {
514 exitCode = 255;
515 break;
516 }
517
518 page = page == null ? 1 : page;
519 if (page < 0) {
520 Instance.getTraceHandler().error("Incorrect page number");
521 exitCode = 255;
522 break;
523 }
524
525 item = item == null ? 0 : item;
526 if (item < 0) {
527 Instance.getTraceHandler().error("Incorrect item number");
528 exitCode = 255;
529 break;
530 }
531
532 if (BasicReader.getReader() == null) {
533 Instance.getTraceHandler()
534 .error(new Exception(
535 "No reader type has been configured"));
536 exitCode = 10;
537 break;
538 }
539
540 try {
541 BasicReader.getReader().searchTag(searchOn, page, item,
542 true, tags.toArray(new Integer[] {}));
543 } catch (IOException e1) {
544 Instance.getTraceHandler().error(e1);
545 }
546
547 break;
548 case HELP:
549 syntax(true);
550 exitCode = 0;
551 break;
552 case SET_READER:
553 exitCode = 255;
554 break;
555 case VERSION:
556 System.out
557 .println(String.format("Fanfix version %s"
558 + "%nhttps://github.com/nikiroo/fanfix/"
559 + "%n\tWritten by Nikiroo",
560 Version.getCurrentVersion()));
561 updates.ok(); // we consider it read
562 break;
563 case START:
564 if (BasicReader.getReader() == null) {
565 Instance.getTraceHandler()
566 .error(new Exception(
567 "No reader type has been configured"));
568 exitCode = 10;
569 break;
570 }
571 BasicReader.getReader().browse(null);
572 break;
573 case SERVER:
574 if (port == null) {
575 exitCode = 255;
576 break;
577 }
578 try {
579 ServerObject server = new RemoteLibraryServer(key, port);
580 server.setTraceHandler(Instance.getTraceHandler());
581 server.run();
582 } catch (IOException e) {
583 Instance.getTraceHandler().error(e);
584 }
585 return;
586 case STOP_SERVER:
587 if (port == null) {
588 exitCode = 255;
589 break;
590 }
591
592 new RemoteLibrary(key, host, port).exit();
593 break;
594 case REMOTE:
595 exitCode = 255; // should not be reachable (REMOTE -> START)
596 break;
597 }
598 }
599
600 try {
601 Instance.getTempFiles().close();
602 } catch (IOException e) {
603 Instance.getTraceHandler()
604 .error(new IOException(
605 "Cannot dispose of the temporary files", e));
606 }
607
608 if (exitCode == 255) {
609 syntax(false);
610 }
611
612 System.exit(exitCode);
613 }
614
615 /**
616 * Import the given resource into the {@link LocalLibrary}.
617 *
618 * @param urlString
619 * the resource to import
620 * @param pg
621 * the optional progress reporter
622 *
623 * @return the exit return code (0 = success)
624 */
625 public static int imprt(String urlString, Progress pg) {
626 try {
627 Story story = Instance.getLibrary().imprt(
628 BasicReader.getUrl(urlString), pg);
629 System.out.println(story.getMeta().getLuid() + ": \""
630 + story.getMeta().getTitle() + "\" imported.");
631 } catch (IOException e) {
632 Instance.getTraceHandler().error(e);
633 return 1;
634 }
635
636 return 0;
637 }
638
639 /**
640 * Export the {@link Story} from the {@link LocalLibrary} to the given
641 * target.
642 *
643 * @param luid
644 * the story LUID
645 * @param typeString
646 * the {@link OutputType} to use
647 * @param target
648 * the target
649 * @param pg
650 * the optional progress reporter
651 *
652 * @return the exit return code (0 = success)
653 */
654 public static int export(String luid, String typeString, String target,
655 Progress pg) {
656 OutputType type = OutputType.valueOfNullOkUC(typeString, null);
657 if (type == null) {
658 Instance.getTraceHandler().error(
659 new Exception(trans(StringId.OUTPUT_DESC, typeString)));
660 return 1;
661 }
662
663 try {
664 Instance.getLibrary().export(luid, type, target, pg);
665 } catch (IOException e) {
666 Instance.getTraceHandler().error(e);
667 return 4;
668 }
669
670 return 0;
671 }
672
673 /**
674 * List the stories of the given source from the {@link LocalLibrary}
675 * (unless NULL is passed, in which case all stories will be listed).
676 *
677 * @param source
678 * the source to list the known stories of, or NULL to list all
679 * stories
680 *
681 * @return the exit return code (0 = success)
682 */
683 private static int list(String source) {
684 List<MetaData> stories;
685 stories = BasicReader.getReader().getLibrary().getListBySource(source);
686
687 for (MetaData story : stories) {
688 String author = "";
689 if (story.getAuthor() != null && !story.getAuthor().isEmpty()) {
690 author = " (" + story.getAuthor() + ")";
691 }
692
693 System.out.println(story.getLuid() + ": " + story.getTitle()
694 + author);
695 }
696 return 0;
697 }
698
699 /**
700 * Start the current reader for this {@link Story}.
701 *
702 * @param story
703 * the LUID of the {@link Story} in the {@link LocalLibrary}
704 * <b>or</b> the {@link Story} {@link URL}
705 * @param chapString
706 * which {@link Chapter} to read (starting at 1), or NULL to get
707 * the {@link Story} description
708 * @param library
709 * TRUE if the source is the {@link Story} LUID, FALSE if it is a
710 * {@link URL}
711 *
712 * @return the exit return code (0 = success)
713 */
714 private static int read(String story, String chapString, boolean library) {
715 try {
716 Reader reader = BasicReader.getReader();
717 if (library) {
718 reader.setMeta(story);
719 } else {
720 reader.setMeta(BasicReader.getUrl(story), null);
721 }
722
723 if (chapString != null) {
724 try {
725 reader.setChapter(Integer.parseInt(chapString));
726 reader.read(true);
727 } catch (NumberFormatException e) {
728 Instance.getTraceHandler().error(
729 new IOException("Chapter number cannot be parsed: "
730 + chapString, e));
731 return 2;
732 }
733 } else {
734 reader.read(true);
735 }
736 } catch (IOException e) {
737 Instance.getTraceHandler().error(e);
738 return 1;
739 }
740
741 return 0;
742 }
743
744 /**
745 * Convert the {@link Story} into another format.
746 *
747 * @param urlString
748 * the source {@link Story} to convert
749 * @param typeString
750 * the {@link OutputType} to convert to
751 * @param target
752 * the target file
753 * @param infoCover
754 * TRUE to also export the cover and info file, even if the given
755 * {@link OutputType} does not usually save them
756 * @param pg
757 * the optional progress reporter
758 *
759 * @return the exit return code (0 = success)
760 */
761 public static int convert(String urlString, String typeString,
762 String target, boolean infoCover, Progress pg) {
763 int exitCode = 0;
764
765 Instance.getTraceHandler().trace("Convert: " + urlString);
766 String sourceName = urlString;
767 try {
768 URL source = BasicReader.getUrl(urlString);
769 sourceName = source.toString();
770 if (source.toString().startsWith("file://")) {
771 sourceName = sourceName.substring("file://".length());
772 }
773
774 OutputType type = OutputType.valueOfAllOkUC(typeString, null);
775 if (type == null) {
776 Instance.getTraceHandler().error(
777 new IOException(trans(StringId.ERR_BAD_OUTPUT_TYPE,
778 typeString)));
779
780 exitCode = 2;
781 } else {
782 try {
783 BasicSupport support = BasicSupport.getSupport(source);
784
785 if (support != null) {
786 Instance.getTraceHandler().trace(
787 "Support found: " + support.getClass());
788 Progress pgIn = new Progress();
789 Progress pgOut = new Progress();
790 if (pg != null) {
791 pg.setMax(2);
792 pg.addProgress(pgIn, 1);
793 pg.addProgress(pgOut, 1);
794 }
795
796 Story story = support.process(pgIn);
797 try {
798 target = new File(target).getAbsolutePath();
799 BasicOutput.getOutput(type, infoCover, infoCover)
800 .process(story, target, pgOut);
801 } catch (IOException e) {
802 Instance.getTraceHandler().error(
803 new IOException(trans(StringId.ERR_SAVING,
804 target), e));
805 exitCode = 5;
806 }
807 } else {
808 Instance.getTraceHandler().error(
809 new IOException(trans(
810 StringId.ERR_NOT_SUPPORTED, source)));
811
812 exitCode = 4;
813 }
814 } catch (IOException e) {
815 Instance.getTraceHandler().error(
816 new IOException(trans(StringId.ERR_LOADING,
817 sourceName), e));
818 exitCode = 3;
819 }
820 }
821 } catch (MalformedURLException e) {
822 Instance.getTraceHandler()
823 .error(new IOException(trans(StringId.ERR_BAD_URL,
824 sourceName), e));
825 exitCode = 1;
826 }
827
828 return exitCode;
829 }
830
831 /**
832 * Simple shortcut method to call {link Instance#getTrans()#getString()}.
833 *
834 * @param id
835 * the ID to translate
836 *
837 * @return the translated result
838 */
839 private static String trans(StringId id, Object... params) {
840 return Instance.getTrans().getString(id, params);
841 }
842
843 /**
844 * Display the correct syntax of the program to the user to stdout, or an
845 * error message if the syntax used was wrong on stderr.
846 *
847 * @param showHelp
848 * TRUE to show the syntax help, FALSE to show "syntax error"
849 */
850 private static void syntax(boolean showHelp) {
851 if (showHelp) {
852 StringBuilder builder = new StringBuilder();
853 for (SupportType type : SupportType.values()) {
854 builder.append(trans(StringId.ERR_SYNTAX_TYPE, type.toString(),
855 type.getDesc()));
856 builder.append('\n');
857 }
858
859 String typesIn = builder.toString();
860 builder.setLength(0);
861
862 for (OutputType type : OutputType.values()) {
863 builder.append(trans(StringId.ERR_SYNTAX_TYPE, type.toString(),
864 type.getDesc(true)));
865 builder.append('\n');
866 }
867
868 String typesOut = builder.toString();
869
870 System.out.println(trans(StringId.HELP_SYNTAX, typesIn, typesOut));
871 } else {
872 System.err.println(trans(StringId.ERR_SYNTAX));
873 }
874 }
875
876 /**
877 * Set the default reader type for this session only (it can be changed in
878 * the configuration file, too, but this value will override it).
879 *
880 * @param readerTypeString
881 * the type
882 */
883 private static int setReaderType(String readerTypeString) {
884 try {
885 ReaderType readerType = ReaderType.valueOf(readerTypeString
886 .toUpperCase());
887 BasicReader.setDefaultReaderType(readerType);
888 return 0;
889 } catch (IllegalArgumentException e) {
890 Instance.getTraceHandler().error(
891 new IOException("Unknown reader type: " + readerTypeString,
892 e));
893 return 1;
894 }
895 }
896 }