Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

CommandLineParser.java 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. /*
  2. * Copyright (c) 2006-2007 Chris Smith, Shane Mc Cormack, Gregory Holmes
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a copy
  5. * of this software and associated documentation files (the "Software"), to deal
  6. * in the Software without restriction, including without limitation the rights
  7. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. * copies of the Software, and to permit persons to whom the Software is
  9. * furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  20. * SOFTWARE.
  21. */
  22. package com.dmdirc.commandline;
  23. import com.dmdirc.util.InvalidAddressException;
  24. import com.dmdirc.util.IrcAddress;
  25. import com.dmdirc.Main;
  26. import com.dmdirc.config.IdentityManager;
  27. import com.dmdirc.util.resourcemanager.ResourceManager;
  28. import java.rmi.RemoteException;
  29. import java.util.ArrayList;
  30. import java.util.List;
  31. /**
  32. * Parses command line arguments for the client.
  33. *
  34. * @author Chris
  35. */
  36. public class CommandLineParser {
  37. /**
  38. * The arguments that the client supports, in groups of four, in the
  39. * following order: short option, long option, description, whether or not
  40. * the option takes an argument.
  41. */
  42. private static final Object[][] ARGUMENTS = new Object[][]{
  43. {'c', "connect", "Connect to the specified server", Boolean.TRUE},
  44. {'d', "directory", "Use the specified configuration directory", Boolean.TRUE},
  45. {'e', "existing", "Try to use an existing instance of DMDirc (use with -c)", Boolean.FALSE},
  46. {'h', "help", "Show command line options and exit", Boolean.FALSE},
  47. {'p', "portable", "Enable portable mode", Boolean.FALSE},
  48. {'r', "disable-reporting", "Disable automatic error reporting", Boolean.FALSE},
  49. {'v', "version", "Display client version and exit", Boolean.FALSE},
  50. };
  51. /** A list of addresses to autoconnect to. */
  52. private final List<IrcAddress> addresses = new ArrayList<IrcAddress>();
  53. /** Whether to disable error reporting or not. */
  54. private boolean disablereporting = false;
  55. /** Whether or not to try and use an existing client. */
  56. private boolean useExisting = false;
  57. /**
  58. * Creates a new instance of CommandLineParser.
  59. *
  60. * @param arguments The arguments to be parsed
  61. */
  62. public CommandLineParser(final String ... arguments) {
  63. boolean inArg = false;
  64. char previousArg = '.';
  65. for (String arg : arguments) {
  66. if (inArg) {
  67. processArgument(previousArg, arg);
  68. inArg = false;
  69. } else {
  70. if (arg.startsWith("--")) {
  71. previousArg = processLongArg(arg.substring(2));
  72. inArg = checkArgument(previousArg);
  73. } else if (arg.charAt(0) == '-') {
  74. previousArg = processShortArg(arg.substring(1));
  75. inArg = checkArgument(previousArg);
  76. } else {
  77. doUnknownArg("Unknown argument: " + arg);
  78. }
  79. }
  80. }
  81. if (inArg) {
  82. doUnknownArg("Missing parameter for argument: " + previousArg);
  83. }
  84. if (useExisting) {
  85. final RemoteInterface server = RemoteServer.getServer();
  86. if (server != null) {
  87. try {
  88. server.connect(addresses);
  89. System.exit(0);
  90. } catch (RemoteException ex) {
  91. // Do nothing
  92. }
  93. }
  94. }
  95. RemoteServer.bind();
  96. }
  97. /**
  98. * Checks whether the specified arg type takes an argument. If it does,
  99. * this method returns true. If it doesn't, the method processes the
  100. * argument and returns false.
  101. *
  102. * @param argument The short code of the argument
  103. * @return True if the arg requires an argument, false otherwise
  104. */
  105. private boolean checkArgument(final char argument) {
  106. boolean needsArg = false;
  107. for (int i = 0; i < ARGUMENTS.length; i++) {
  108. if (argument == ARGUMENTS[i][0]) {
  109. needsArg = (Boolean) ARGUMENTS[i][3];
  110. break;
  111. }
  112. }
  113. if (needsArg) {
  114. return true;
  115. } else {
  116. processArgument(argument, null);
  117. return false;
  118. }
  119. }
  120. /**
  121. * Processes the specified string as a single long argument.
  122. *
  123. * @param arg The string entered
  124. * @return The short form of the corresponding argument
  125. */
  126. private char processLongArg(final String arg) {
  127. for (int i = 0; i < ARGUMENTS.length; i++) {
  128. if (arg.equalsIgnoreCase((String) ARGUMENTS[i][1])) {
  129. return (Character) ARGUMENTS[i][0];
  130. }
  131. }
  132. doUnknownArg("Unknown argument: " + arg);
  133. exit();
  134. return '.';
  135. }
  136. /**
  137. * Processes the specified string as a single short argument.
  138. *
  139. * @param arg The string entered
  140. * @return The short form of the corresponding argument
  141. */
  142. private char processShortArg(final String arg) {
  143. for (int i = 0; i < ARGUMENTS.length; i++) {
  144. if (arg.charAt(0) == ARGUMENTS[i][0]) {
  145. return arg.charAt(0);
  146. }
  147. }
  148. doUnknownArg("Unknown argument: " + arg);
  149. exit();
  150. return '.';
  151. }
  152. /**
  153. * Processes the sepcified command-line argument.
  154. *
  155. * @param arg The short form of the argument used
  156. * @param param The (optional) string parameter for the option
  157. */
  158. private void processArgument(final char arg, final String param) {
  159. switch (arg) {
  160. case 'c':
  161. doConnect(param);
  162. break;
  163. case 'd':
  164. doDirectory(param);
  165. break;
  166. case 'e':
  167. useExisting = true;
  168. break;
  169. case 'h':
  170. doHelp();
  171. break;
  172. case 'p':
  173. doDirectory(ResourceManager.getCurrentWorkingDirectory());
  174. break;
  175. case 'r':
  176. disablereporting = true;
  177. break;
  178. case 'v':
  179. doVersion();
  180. break;
  181. default:
  182. // This really shouldn't ever happen, but we'll handle it nicely
  183. // anyway.
  184. doUnknownArg("Unknown argument: " + arg);
  185. break;
  186. }
  187. }
  188. /**
  189. * Informs the user that they entered an unknown argument, prints the
  190. * client help, and exits.
  191. *
  192. * @param message The message about the unknown argument to be displayed
  193. */
  194. private void doUnknownArg(final String message) {
  195. System.out.println(message);
  196. System.out.println();
  197. doHelp();
  198. }
  199. /**
  200. * Exits DMDirc.
  201. */
  202. private void exit() {
  203. System.exit(0);
  204. }
  205. /**
  206. * Handles the --connect argument.
  207. *
  208. * @param address The address the user told us to connect to
  209. */
  210. private void doConnect(final String address) {
  211. IrcAddress myAddress = null;
  212. try {
  213. myAddress = new IrcAddress(address);
  214. addresses.add(myAddress);
  215. } catch (InvalidAddressException ex) {
  216. doUnknownArg("Invalid address specified: " + ex.getMessage());
  217. }
  218. }
  219. /**
  220. * Sets the config directory to the one specified.
  221. *
  222. * @param dir The new config directory
  223. */
  224. private void doDirectory(final String dir) {
  225. Main.setConfigDir(dir);
  226. }
  227. /**
  228. * Prints out the client version and exits.
  229. */
  230. private void doVersion() {
  231. System.out.println("DMDirc - a cross-platform, open-source IRC client.");
  232. System.out.println();
  233. System.out.println(" Version: " + Main.VERSION);
  234. System.out.println(" Release date: " + Main.RELEASE_DATE);
  235. System.out.println(" Channel: " + Main.UPDATE_CHANNEL);
  236. exit();
  237. }
  238. /**
  239. * Prints out client help and exits.
  240. */
  241. private void doHelp() {
  242. System.out.println("Usage: java -jar DMDirc.jar [options]");
  243. System.out.println();
  244. System.out.println("Valid options:");
  245. System.out.println();
  246. int maxLength = 0;
  247. for (Object[] arg : ARGUMENTS) {
  248. final String needsArg = ((Boolean) arg[3]) ? " <argument>" : "";
  249. if ((arg[1] + needsArg).length() > maxLength) {
  250. maxLength = (arg[1] + needsArg).length();
  251. }
  252. }
  253. for (Object[] arg : ARGUMENTS) {
  254. final String needsArg = ((Boolean) arg[3]) ? " <argument>" : "";
  255. final StringBuilder desc = new StringBuilder(maxLength + 1);
  256. desc.append(arg[1]);
  257. while (desc.length() < maxLength + 1) {
  258. desc.append(' ');
  259. }
  260. System.out.print(" -" + arg[0] + needsArg);
  261. System.out.println(" --" + desc + needsArg + " " + arg[2]);
  262. System.out.println();
  263. }
  264. exit();
  265. }
  266. /**
  267. * Applies any applicable settings to the config identity.
  268. */
  269. public void applySettings() {
  270. if (disablereporting) {
  271. IdentityManager.getConfigIdentity().setOption("temp", "noerrorreporting", true);
  272. }
  273. }
  274. /**
  275. * Processes arguments once the client has been loaded properly.
  276. * This allows us to auto-connect to servers, etc.
  277. */
  278. public void processArguments() {
  279. for (IrcAddress address : addresses) {
  280. address.connect();
  281. }
  282. }
  283. }