X-Git-Url: http://git.nikiroo.be/?p=nikiroo-utils.git;a=blobdiff_plain;f=Main.java;h=35365444682489d81adf7b25ed864416d6c47abe;hp=961816a3f63e96afc4611489e5d83d85c9e2898a;hb=258e065f81071a861711ef935dca3ec5563f4360;hpb=371a36bd5f5d0e46038491ecfdd18653fe4d6f61 diff --git a/Main.java b/Main.java index 961816a..3536544 100644 --- a/Main.java +++ b/Main.java @@ -19,17 +19,18 @@ import be.nikiroo.fanfix.library.CacheLibrary; import be.nikiroo.fanfix.library.LocalLibrary; import be.nikiroo.fanfix.library.RemoteLibrary; import be.nikiroo.fanfix.library.RemoteLibraryServer; +import be.nikiroo.fanfix.library.WebLibrary; +import be.nikiroo.fanfix.library.WebLibraryServer; import be.nikiroo.fanfix.output.BasicOutput; import be.nikiroo.fanfix.output.BasicOutput.OutputType; import be.nikiroo.fanfix.reader.BasicReader; -import be.nikiroo.fanfix.reader.Reader; -import be.nikiroo.fanfix.reader.Reader.ReaderType; +import be.nikiroo.fanfix.reader.CliReader; import be.nikiroo.fanfix.searchable.BasicSearchable; import be.nikiroo.fanfix.supported.BasicSupport; import be.nikiroo.fanfix.supported.SupportType; import be.nikiroo.utils.Progress; import be.nikiroo.utils.Version; -import be.nikiroo.utils.serial.server.ServerObject; +import be.nikiroo.utils.VersionCheck; /** * Main program entry point. @@ -38,7 +39,7 @@ import be.nikiroo.utils.serial.server.ServerObject; */ public class Main { private enum MainAction { - 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 + IMPORT, EXPORT, CONVERT, READ, READ_URL, LIST, HELP, START, VERSION, SERVER, STOP_SERVER, REMOTE, SET_SOURCE, SET_TITLE, SET_AUTHOR, SEARCH, SEARCH_TAG } /** @@ -76,18 +77,32 @@ public class Main { *
  • --set-source [id] [new source]: change the source of the given story
  • *
  • --set-title [id] [new title]: change the title of the given story
  • *
  • --set-author [id] [new author]: change the author of the given story
  • - *
  • --set-reader [reader type]: set the reader type to CLI, TUI or LOCAL - * for this command
  • *
  • --version: get the version of the program
  • *
  • --server: start the server mode (see config file for parameters)
  • *
  • --stop-server: stop the running server on this port if any
  • - *
  • --remote [key] [host] [port]: use a the given remote library
  • + *
  • --remote [key] [host] [port]: use the given remote library
  • * * * @param args * see method description */ public static void main(String[] args) { + new Main().start(args); + } + + /** + * Start the default handling for the application. + *

    + * If specific actions were asked (with correct parameters), they will be + * forwarded to the different protected methods that you can override. + *

    + * At the end of the method, {@link Main#exit(int)} will be called; by + * default, it calls {@link System#exit(int)} if the status is not 0. + * + * @param args + * the arguments received from the system + */ + public void start(String [] args) { // Only one line, but very important: Instance.init(); @@ -113,6 +128,9 @@ public class Main { int exitCode = 0; for (int i = 0; exitCode == 0 && i < args.length; i++) { + if (args[i] == null) + continue; + // Action (--) handling: if (!noMoreActions && args[i].startsWith("--")) { if (args[i].equals("--")) { @@ -314,10 +332,6 @@ public class Main { case HELP: exitCode = 255; break; - case SET_READER: - exitCode = setReaderType(args[i]); - action = MainAction.START; - break; case START: exitCode = 255; // not supposed to be selected by user break; @@ -338,11 +352,19 @@ public class Main { } else if (port == null) { port = Integer.parseInt(args[i]); - BasicLibrary lib = new RemoteLibrary(key, host, port); - lib = new CacheLibrary(Instance.getInstance().getRemoteDir(host), lib, + BasicLibrary lib; + if (host.startsWith("http://") + || host.startsWith("https://")) { + lib = new WebLibrary(key, host, port); + } else { + lib = new RemoteLibrary(key, host, port); + } + + lib = new CacheLibrary( + Instance.getInstance().getRemoteDir(host), lib, Instance.getInstance().getUiConfig()); - BasicReader.setDefaultLibrary(lib); + Instance.getInstance().setLibrary(lib); action = MainAction.START; } else { @@ -379,45 +401,60 @@ public class Main { Progress pg = new Progress(); mainProgress.addProgress(pg, mainProgress.getMax()); - VersionCheck updates = VersionCheck.check(); - if (updates.isNewVersionAvailable()) { - // Sent to syserr so not to cause problem if one tries to capture a - // story content in text mode - System.err - .println("A new version of the program is available at https://github.com/nikiroo/fanfix/releases"); - System.err.println(""); - for (Version v : updates.getNewer()) { - System.err.println("\tVersion " + v); - System.err.println("\t-------------"); - System.err.println(""); - for (String it : updates.getChanges().get(v)) { - System.err.println("\t- " + it); - } - System.err.println(""); - } - } + VersionCheck updates = checkUpdates(); if (exitCode == 0) { switch (action) { case IMPORT: - exitCode = imprt(urlString, pg); - updates.ok(); // we consider it read + if (updates != null) { + // we consider it read + Instance.getInstance().setVersionChecked(); + } + + try { + exitCode = imprt(BasicReader.getUrl(urlString), pg); + } catch (MalformedURLException e) { + Instance.getInstance().getTraceHandler().error(e); + exitCode = 1; + } + break; case EXPORT: - exitCode = export(luid, sourceString, target, pg); - updates.ok(); // we consider it read + if (updates != null) { + // we consider it read + Instance.getInstance().setVersionChecked(); + } + + OutputType exportType = OutputType.valueOfNullOkUC(sourceString, null); + if (exportType == null) { + Instance.getInstance().getTraceHandler().error(new Exception(trans(StringId.OUTPUT_DESC, sourceString))); + exitCode = 1; + break; + } + + exitCode = export(luid, exportType, target, pg); + break; case CONVERT: - exitCode = convert(urlString, sourceString, target, + if (updates != null) { + // we consider it read + Instance.getInstance().setVersionChecked(); + } + + OutputType convertType = OutputType.valueOfAllOkUC(sourceString, null); + if (convertType == null) { + Instance.getInstance().getTraceHandler() + .error(new IOException(trans(StringId.ERR_BAD_OUTPUT_TYPE, sourceString))); + + exitCode = 2; + break; + } + + exitCode = convert(urlString, convertType, target, plusInfo == null ? false : plusInfo, pg); - updates.ok(); // we consider it read + break; case LIST: - if (BasicReader.getReader() == null) { - Instance.getInstance().getTraceHandler().error(new Exception("No reader type has been configured")); - exitCode = 10; - break; - } exitCode = list(sourceString); break; case SET_SOURCE: @@ -445,20 +482,70 @@ public class Main { } break; case READ: - if (BasicReader.getReader() == null) { - Instance.getInstance().getTraceHandler().error(new Exception("No reader type has been configured")); - exitCode = 10; + if (luid == null || luid.isEmpty()) { + syntax(false); + exitCode = 255; break; } - exitCode = read(luid, chapString, true); + + try { + Integer chap = null; + if (chapString != null) { + try { + chap = Integer.parseInt(chapString); + } catch (NumberFormatException e) { + Instance.getInstance().getTraceHandler().error(new IOException( + "Chapter number cannot be parsed: " + chapString, e)); + exitCode = 2; + break; + } + } + + BasicLibrary lib = Instance.getInstance().getLibrary(); + exitCode = read(lib.getStory(luid, null), chap); + } catch (IOException e) { + Instance.getInstance().getTraceHandler() + .error(new IOException("Failed to read book", e)); + exitCode = 2; + } + break; case READ_URL: - if (BasicReader.getReader() == null) { - Instance.getInstance().getTraceHandler().error(new Exception("No reader type has been configured")); - exitCode = 10; + if (urlString == null || urlString.isEmpty()) { + syntax(false); + exitCode = 255; break; } - exitCode = read(urlString, chapString, false); + + try { + Integer chap = null; + if (chapString != null) { + try { + chap = Integer.parseInt(chapString); + } catch (NumberFormatException e) { + Instance.getInstance().getTraceHandler().error(new IOException( + "Chapter number cannot be parsed: " + chapString, e)); + exitCode = 2; + break; + } + } + + BasicSupport support = BasicSupport + .getSupport(BasicReader.getUrl(urlString)); + if (support == null) { + Instance.getInstance().getTraceHandler() + .error("URL not supported: " + urlString); + exitCode = 2; + break; + } + + exitCode = read(support.process(null), chap); + } catch (IOException e) { + Instance.getInstance().getTraceHandler() + .error(new IOException("Failed to read book", e)); + exitCode = 2; + } + break; case SEARCH: page = page == null ? 1 : page; @@ -475,25 +562,22 @@ public class Main { break; } - if (BasicReader.getReader() == null) { - Instance.getInstance().getTraceHandler().error(new Exception("No reader type has been configured")); - exitCode = 10; - break; - } - - try { - if (searchOn == null) { - BasicReader.getReader().search(true); - } else if (search != null) { - - BasicReader.getReader().search(searchOn, search, page, - item, true); - } else { - exitCode = 255; + if (searchOn == null) { + try { + search(); + } catch (IOException e) { + Instance.getInstance().getTraceHandler().error(e); + exitCode = 1; } - } catch (IOException e1) { - Instance.getInstance().getTraceHandler().error(e1); - exitCode = 20; + } else if (search != null) { + try { + searchKeywords(searchOn, search, page, item); + } catch (IOException e) { + Instance.getInstance().getTraceHandler().error(e); + exitCode = 20; + } + } else { + exitCode = 255; } break; @@ -517,17 +601,11 @@ public class Main { break; } - if (BasicReader.getReader() == null) { - Instance.getInstance().getTraceHandler().error(new Exception("No reader type has been configured")); - exitCode = 10; - break; - } - try { - BasicReader.getReader().searchTag(searchOn, page, item, - true, tags.toArray(new Integer[] {})); - } catch (IOException e1) { - Instance.getInstance().getTraceHandler().error(e1); + searchTags(searchOn, page, item, + tags.toArray(new Integer[] {})); + } catch (IOException e) { + Instance.getInstance().getTraceHandler().error(e); } break; @@ -535,52 +613,66 @@ public class Main { syntax(true); exitCode = 0; break; - case SET_READER: - exitCode = 255; - break; case VERSION: + if (updates != null) { + // we consider it read + Instance.getInstance().setVersionChecked(); + } + System.out .println(String.format("Fanfix version %s" + "%nhttps://github.com/nikiroo/fanfix/" + "%n\tWritten by Nikiroo", Version.getCurrentVersion())); - updates.ok(); // we consider it read break; case START: - if (BasicReader.getReader() == null) { - Instance.getInstance().getTraceHandler().error(new Exception("No reader type has been configured")); - exitCode = 10; - break; - } try { - BasicReader.getReader().browse(null); + start(); } catch (IOException e) { Instance.getInstance().getTraceHandler().error(e); exitCode = 66; } break; case SERVER: - key = Instance.getInstance().getConfig().getString(Config.SERVER_KEY); - port = Instance.getInstance().getConfig().getInteger(Config.SERVER_PORT); - if (port == null) { - System.err.println("No port configured in the config file"); - exitCode = 15; - break; - } try { - ServerObject server = new RemoteLibraryServer(key, port); - server.setTraceHandler(Instance.getInstance().getTraceHandler()); - server.run(); + startServer(); } catch (IOException e) { Instance.getInstance().getTraceHandler().error(e); } - return; + + break; case STOP_SERVER: // Can be given via "--remote XX XX XX" - if (key == null) - key = Instance.getInstance().getConfig().getString(Config.SERVER_KEY); - if (port == null) + if (key == null) { + key = Instance.getInstance().getConfig() + .getString(Config.SERVER_KEY); + + // If a subkey in RW mode exists, use it + for (String subkey : Instance.getInstance().getConfig() + .getList(Config.SERVER_ALLOWED_SUBKEYS, + new ArrayList())) { + if ((subkey + "|").contains("|rw|")) { + key = key + "|" + subkey; + break; + } + } + } + + if (port == null) { port = Instance.getInstance().getConfig().getInteger(Config.SERVER_PORT); + } + + if (host == null) { + String mode = Instance.getInstance().getConfig() + .getString(Config.SERVER_MODE, "fanfix"); + if ("http".equals(mode)) { + host = "http://localhost"; + } else if ("https".equals(mode)) { + host = "https://localhost"; + } else if ("fanfix".equals(mode)) { + host = "fanfix://localhost"; + } + } if (port == null) { System.err.println("No port given nor configured in the config file"); @@ -588,7 +680,7 @@ public class Main { break; } try { - new RemoteLibrary(key, host, port).exit(); + stopServer(key, host, port); } catch (SSLException e) { Instance.getInstance().getTraceHandler().error( "Bad access key for remote library"); @@ -608,29 +700,114 @@ public class Main { try { Instance.getInstance().getTempFiles().close(); } catch (IOException e) { - Instance.getInstance().getTraceHandler().error(new IOException("Cannot dispose of the temporary files", e)); + Instance.getInstance().getTraceHandler().error(new IOException( + "Cannot dispose of the temporary files", e)); } if (exitCode == 255) { syntax(false); } - System.exit(exitCode); + exit(exitCode); + } + + /** + * A normal invocation of the program (without parameters or at least + * without "action" parameters). + *

    + * You will probably want to override that one if you offer a user + * interface. + * + * @throws IOException + * in case of I/O error + */ + protected void start() throws IOException { + new CliReader().listBooks(null); + } + + /** + * Will check if updates are available, synchronously. + *

    + * For this, it will simply forward the call to + * {@link Main#checkUpdates(String)} with a value of "nikiroo/fanfix". + *

    + * You may want to override it so you call the forward method with the right + * parameters (or also if you want it to be asynchronous). + * + * @return the newer version information or NULL if nothing new + */ + protected VersionCheck checkUpdates() { + return checkUpdates("nikiroo/fanfix"); } + /** + * Will check if updates are available on a specific GitHub project. + *

    + * Will be called by {@link Main#checkUpdates()}, but if you override that + * one you mall call it with another project. + * + * @param githubProject + * the GitHub project, for instance "nikiroo/fanfix" + * + * @return the newer version information or NULL if nothing new + */ + protected VersionCheck checkUpdates(String githubProject) { + try { + VersionCheck updates = VersionCheck.check(githubProject, + Instance.getInstance().getTrans().getLocale()); + if (updates.isNewVersionAvailable()) { + notifyUpdates(updates); + return updates; + } + } catch (IOException e) { + // Maybe no internet. Do not report any update. + } + + return null; + } + + /** + * Notify the user about available updates. + *

    + * Will only be called when a version is available. + *

    + * Note that you can call {@link Instance#setVersionChecked()} on it if the + * user has read the information (by default, it is marked read only on + * certain other actions). + * + * @param updates + * the new version information + */ + protected void notifyUpdates(VersionCheck updates) { + // Sent to syserr so not to cause problem if one tries to capture a + // story content in text mode + System.err.println( + "A new version of the program is available at https://github.com/nikiroo/fanfix/releases"); + System.err.println(""); + for (Version v : updates.getNewer()) { + System.err.println("\tVersion " + v); + System.err.println("\t-------------"); + System.err.println(""); + for (String it : updates.getChanges().get(v)) { + System.err.println("\t- " + it); + } + System.err.println(""); + } + } + /** * Import the given resource into the {@link LocalLibrary}. * - * @param urlString + * @param url * the resource to import * @param pg * the optional progress reporter * * @return the exit return code (0 = success) */ - public static int imprt(String urlString, Progress pg) { + protected static int imprt(URL url, Progress pg) { try { - MetaData meta = Instance.getInstance().getLibrary().imprt(BasicReader.getUrl(urlString), pg); + MetaData meta = Instance.getInstance().getLibrary().imprt(url, pg); System.out.println(meta.getLuid() + ": \"" + meta.getTitle() + "\" imported."); } catch (IOException e) { Instance.getInstance().getTraceHandler().error(e); @@ -646,7 +823,7 @@ public class Main { * * @param luid * the story LUID - * @param typeString + * @param type * the {@link OutputType} to use * @param target * the target @@ -655,14 +832,8 @@ public class Main { * * @return the exit return code (0 = success) */ - public static int export(String luid, String typeString, String target, + protected static int export(String luid, OutputType type, String target, Progress pg) { - OutputType type = OutputType.valueOfNullOkUC(typeString, null); - if (type == null) { - Instance.getInstance().getTraceHandler().error(new Exception(trans(StringId.OUTPUT_DESC, typeString))); - return 1; - } - try { Instance.getInstance().getLibrary().export(luid, type, target, pg); } catch (IOException e) { @@ -672,7 +843,7 @@ public class Main { return 0; } - + /** * List the stories of the given source from the {@link LocalLibrary} * (unless NULL is passed, in which case all stories will be listed). @@ -683,10 +854,9 @@ public class Main { * * @return the exit return code (0 = success) */ - private static int list(String source) { - BasicReader.setDefaultReaderType(ReaderType.CLI); + protected int list(String source) { try { - BasicReader.getReader().browse(source); + new CliReader().listBooks(source); } catch (IOException e) { Instance.getInstance().getTraceHandler().error(e); return 66; @@ -699,41 +869,30 @@ public class Main { * Start the current reader for this {@link Story}. * * @param story - * the LUID of the {@link Story} in the {@link LocalLibrary} - * or the {@link Story} {@link URL} - * @param chapString + * the story to read + * @param chap * which {@link Chapter} to read (starting at 1), or NULL to get * the {@link Story} description - * @param library - * TRUE if the source is the {@link Story} LUID, FALSE if it is a - * {@link URL} * * @return the exit return code (0 = success) */ - private static int read(String story, String chapString, boolean library) { - try { - Reader reader = BasicReader.getReader(); - if (library) { - reader.setMeta(story); - } else { - reader.setMeta(BasicReader.getUrl(story), null); - } - - if (chapString != null) { - try { - reader.setChapter(Integer.parseInt(chapString)); - reader.read(true); - } catch (NumberFormatException e) { - Instance.getInstance().getTraceHandler() - .error(new IOException("Chapter number cannot be parsed: " + chapString, e)); - return 2; + protected int read(Story story, Integer chap) { + if (story != null) { + try { + if (chap == null) { + new CliReader().listChapters(story); + } else { + new CliReader().printChapter(story, chap); } - } else { - reader.read(true); + } catch (IOException e) { + Instance.getInstance().getTraceHandler() + .error(new IOException("Failed to read book", e)); + return 2; } - } catch (IOException e) { - Instance.getInstance().getTraceHandler().error(e); - return 1; + } else { + Instance.getInstance().getTraceHandler() + .error("Cannot find book: " + story); + return 2; } return 0; @@ -744,7 +903,7 @@ public class Main { * * @param urlString * the source {@link Story} to convert - * @param typeString + * @param type * the {@link OutputType} to convert to * @param target * the target file @@ -756,7 +915,7 @@ public class Main { * * @return the exit return code (0 = success) */ - public static int convert(String urlString, String typeString, + protected int convert(String urlString, OutputType type, String target, boolean infoCover, Progress pg) { int exitCode = 0; @@ -769,46 +928,42 @@ public class Main { sourceName = sourceName.substring("file://".length()); } - OutputType type = OutputType.valueOfAllOkUC(typeString, null); - if (type == null) { - Instance.getInstance().getTraceHandler() - .error(new IOException(trans(StringId.ERR_BAD_OUTPUT_TYPE, typeString))); + try { + BasicSupport support = BasicSupport.getSupport(source); - exitCode = 2; - } else { - try { - BasicSupport support = BasicSupport.getSupport(source); - - if (support != null) { - Instance.getInstance().getTraceHandler().trace("Support found: " + support.getClass()); - Progress pgIn = new Progress(); - Progress pgOut = new Progress(); - if (pg != null) { - pg.setMax(2); - pg.addProgress(pgIn, 1); - pg.addProgress(pgOut, 1); - } + if (support != null) { + Instance.getInstance().getTraceHandler() + .trace("Support found: " + support.getClass()); + Progress pgIn = new Progress(); + Progress pgOut = new Progress(); + if (pg != null) { + pg.setMax(2); + pg.addProgress(pgIn, 1); + pg.addProgress(pgOut, 1); + } - Story story = support.process(pgIn); - try { - target = new File(target).getAbsolutePath(); - BasicOutput.getOutput(type, infoCover, infoCover).process(story, target, pgOut); - } catch (IOException e) { - Instance.getInstance().getTraceHandler() - .error(new IOException(trans(StringId.ERR_SAVING, target), e)); - exitCode = 5; - } - } else { + Story story = support.process(pgIn); + try { + target = new File(target).getAbsolutePath(); + BasicOutput.getOutput(type, infoCover, infoCover) + .process(story, target, pgOut); + } catch (IOException e) { Instance.getInstance().getTraceHandler() - .error(new IOException(trans( StringId.ERR_NOT_SUPPORTED, source))); - - exitCode = 4; + .error(new IOException( + trans(StringId.ERR_SAVING, target), e)); + exitCode = 5; } - } catch (IOException e) { + } else { Instance.getInstance().getTraceHandler() - .error(new IOException(trans(StringId.ERR_LOADING, sourceName), e)); - exitCode = 3; + .error(new IOException( + trans(StringId.ERR_NOT_SUPPORTED, source))); + + exitCode = 4; } + } catch (IOException e) { + Instance.getInstance().getTraceHandler().error(new IOException( + trans(StringId.ERR_LOADING, sourceName), e)); + exitCode = 3; } } catch (MalformedURLException e) { Instance.getInstance().getTraceHandler().error(new IOException(trans(StringId.ERR_BAD_URL, sourceName), e)); @@ -818,18 +973,6 @@ public class Main { return exitCode; } - /** - * Simple shortcut method to call {link Instance#getTrans()#getString()}. - * - * @param id - * the ID to translate - * - * @return the translated result - */ - private static String trans(StringId id, Object... params) { - return Instance.getInstance().getTrans().getString(id, params); - } - /** * Display the correct syntax of the program to the user to stdout, or an * error message if the syntax used was wrong on stderr. @@ -837,7 +980,7 @@ public class Main { * @param showHelp * TRUE to show the syntax help, FALSE to show "syntax error" */ - private static void syntax(boolean showHelp) { + protected void syntax(boolean showHelp) { if (showHelp) { StringBuilder builder = new StringBuilder(); for (SupportType type : SupportType.values()) { @@ -864,22 +1007,135 @@ public class Main { } /** - * Set the default reader type for this session only (it can be changed in - * the configuration file, too, but this value will override it). + * Starts a search operation (i.e., list the available web sites we can + * search on). * - * @param readerTypeString - * the type + * @throws IOException + * in case of I/O errors */ - private static int setReaderType(String readerTypeString) { - try { - ReaderType readerType = ReaderType.valueOf(readerTypeString - .toUpperCase()); - BasicReader.setDefaultReaderType(readerType); - return 0; - } catch (IllegalArgumentException e) { - Instance.getInstance().getTraceHandler() - .error(new IOException("Unknown reader type: " + readerTypeString, e)); - return 1; + protected void search() throws IOException { + new CliReader().listSearchables(); + } + + /** + * Search for books by keywords on the given supported web site. + * + * @param searchOn + * the web site to search on + * @param search + * the keyword to look for + * @param page + * the page of results to get, or 0 to inquire about the number + * of pages + * @param item + * the index of the book we are interested by, or 0 to query + * about how many books are in that page of results + * + * @throws IOException + * in case of I/O error + */ + protected void searchKeywords(SupportType searchOn, String search, + int page, Integer item) throws IOException { + new CliReader().searchBooksByKeyword(searchOn, search, page, item); + } + + /** + * Search for books by tags on the given supported web site. + * + * @param searchOn + * the web site to search on + * @param page + * the page of results to get, or 0 to inquire about the number + * of pages + * @param item + * the index of the book we are interested by, or 0 to query + * about how many books are in that page of results + * @param tags + * the tags to look for + * + * @throws IOException + * in case of I/O error + */ + protected void searchTags(SupportType searchOn, Integer page, Integer item, + Integer[] tags) throws IOException { + new CliReader().searchBooksByTag(searchOn, page, item, tags); + } + + /** + * Start a Fanfix server. + * + * @throws IOException + * in case of I/O errors + * @throws SSLException + * when the key was not accepted + */ + private void startServer() throws IOException { + String mode = Instance.getInstance().getConfig() + .getString(Config.SERVER_MODE, "fanfix"); + if (mode.equals("fanfix")) { + RemoteLibraryServer server = new RemoteLibraryServer(); + server.setTraceHandler(Instance.getInstance().getTraceHandler()); + server.run(); + } else if (mode.equals("http")) { + WebLibraryServer server = new WebLibraryServer(false); + server.setTraceHandler(Instance.getInstance().getTraceHandler()); + server.run(); + } else if (mode.equals("https")) { + WebLibraryServer server = new WebLibraryServer(true); + server.setTraceHandler(Instance.getInstance().getTraceHandler()); + server.run(); + } else { + throw new IOException("Unknown server mode: " + mode); + } + } + + /** + * Stop a running Fanfix server. + * + * @param key + * the key to contact the Fanfix server + * @param host + * the host on which it runs + * @param port + * the port on which it runs + * + * @throws IOException + * in case of I/O errors + * @throws SSLException + * when the key was not accepted + */ + private void stopServer(String key, String host, int port) + throws IOException, SSLException { + if (host.startsWith("http://") || host.startsWith("https://")) { + new WebLibrary(key, host, port).stop(); + } else { + new RemoteLibrary(key, host, port).stop(); } } + + /** + * We are done and ready to exit. + *

    + * By default, it will call {@link System#exit(int)} if the status is not 0. + * + * @param status + * the exit status + */ + protected void exit(int status) { + if (status != 0) { + System.exit(status); + } + } + + /** + * Simple shortcut method to call {link Instance#getTrans()#getString()}. + * + * @param id + * the ID to translate + * + * @return the translated result + */ + static private String trans(StringId id, Object... params) { + return Instance.getInstance().getTrans().getString(id, params); + } }