PageRenderTime 57ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 1ms

/src/edu/illinois/cs/comoto/jplag/ExampleClient.java

https://bitbucket.org/cemeyer2/jplag
Java | 931 lines | 623 code | 90 blank | 218 comment | 174 complexity | 29bd554671172d4f66366033654eb99e MD5 | raw file
  1. /*
  2. * University of Illinois/NCSA
  3. * Open Source License
  4. *
  5. * Copyright (c) 2012 University of Illinois at Urbana-Champaign.
  6. * All rights reserved.
  7. *
  8. * Permission is hereby granted, free of charge, to any person obtaining
  9. * a copy of this software and associated documentation files (the
  10. * "Software"), to deal with the Software without restriction, including
  11. * without limitation the rights to use, copy, modify, merge, publish,
  12. * distribute, sublicense, and/or sell copies of the Software, and to
  13. * permit persons to whom the Software is furnished to do so, subject to
  14. * the following conditions:
  15. *
  16. * * Redistributions of source code must retain the above copyright
  17. * notice, this list of conditions and the following disclaimers.
  18. *
  19. * * Redistributions in binary form must reproduce the above
  20. * copyright notice, this list of conditions and the following
  21. * disclaimers in the documentation and/or other materials provided
  22. * with the distribution.
  23. *
  24. * * Neither the names of the CoMoTo Project team, the University of
  25. * Illinois at Urbana-Champaign, nor the names of its contributors
  26. * may be used to endorse or promote products derived from this
  27. * Software without specific prior written permission.
  28. *
  29. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  30. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  31. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  32. * IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
  33. * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
  34. * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  35. * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
  36. */
  37. package edu.illinois.cs.comoto.jplag;
  38. import com.sun.xml.rpc.client.ClientTransportException;
  39. import com.sun.xml.rpc.util.exception.JAXRPCExceptionBase;
  40. import edu.illinois.cs.comoto.jplag.util.JPlagClientAccessHandler;
  41. import edu.illinois.cs.comoto.jplag.util.ZipUtil;
  42. import edu.illinois.cs.comoto.jplag.wsdl.*;
  43. import javax.net.ssl.HttpsURLConnection;
  44. import javax.net.ssl.SSLContext;
  45. import javax.net.ssl.TrustManager;
  46. import javax.net.ssl.X509TrustManager;
  47. import javax.xml.rpc.handler.Handler;
  48. import javax.xml.rpc.handler.HandlerChain;
  49. import java.io.*;
  50. import java.rmi.RemoteException;
  51. import java.security.cert.X509Certificate;
  52. import java.text.SimpleDateFormat;
  53. import java.util.Date;
  54. import java.util.Iterator;
  55. import java.util.Vector;
  56. /**
  57. * Created by IntelliJ IDEA.
  58. * User: chuck
  59. * Date: 1/26/11
  60. * Time: 1:59 PM
  61. * To change this template use File | Settings | File Templates.
  62. */
  63. public class ExampleClient {
  64. /*
  65. * Status constants
  66. */
  67. public static final int JPLAG_UPLOADING = 0;
  68. public static final int JPLAG_INQUEUE = 50;
  69. public static final int JPLAG_PARSING = 100;
  70. public static final int JPLAG_COMPARING = 200;
  71. public static final int JPLAG_GENRESULT = 230;
  72. public static final int JPLAG_PACKRESULT = 250;
  73. public static final int JPLAG_DONE = 300;
  74. public static final int JPLAG_ERROR = 400;
  75. /*
  76. * Login data
  77. */
  78. private String username = null;
  79. private String password = null;
  80. /**
  81. * Options for JPlag specified by the command line
  82. */
  83. private Option option = new Option();
  84. /**
  85. * Name of directory where the result pages will be stored
  86. */
  87. private String resultDirName = "result";
  88. /**
  89. * True, if the user wants to get a list of his submissions on the server
  90. */
  91. private boolean listSubmissions = false;
  92. /**
  93. * The number of the submission to be downloaded plus 1 or 0
  94. */
  95. private int downloadResultNumber = 0;
  96. /**
  97. * The number of the submission to be cancelled plus 1 or 0
  98. */
  99. private int cancelSubmissionNumber = 0;
  100. /**
  101. * Suffix array generated from the suffix option or the language info
  102. * suffix array
  103. */
  104. private String[] suffixes = null;
  105. /**
  106. * Filename filter used by collectInDir()
  107. */
  108. private FilenameFilter subdirFileFilter = null;
  109. /**
  110. * Current position of progress bar
  111. */
  112. private int progressPos;
  113. /**
  114. * Maximum position of progress bar
  115. */
  116. private int progressMax;
  117. /**
  118. * The stub for the JPlag Web Service
  119. */
  120. private JPlagTyp_Stub stub = null;
  121. /**
  122. * Helper function to easily evaluate web service related exceptions
  123. *
  124. * @param e Exception thrown by a stub method
  125. */
  126. public static void checkException(Exception e) {
  127. if (e instanceof JPlagException) {
  128. JPlagException je = (JPlagException) e;
  129. System.out.println("JPlagException: " + je.getDescription()
  130. + "\n" + je.getRepair());
  131. } else if (e instanceof RemoteException) {
  132. RemoteException re = (RemoteException) e;
  133. Throwable cause = re.getCause();
  134. if (cause != null && cause instanceof ClientTransportException) {
  135. cause = ((JAXRPCExceptionBase) cause).getLinkedException();
  136. if (cause != null) {
  137. System.out.println("Connection exception: "
  138. + cause.getMessage());
  139. return;
  140. }
  141. }
  142. System.out.println("Unexpected RemoteException: "
  143. + re.getMessage());
  144. re.printStackTrace();
  145. } else {
  146. System.out.println("Unexpected Exception: " + e.getMessage());
  147. e.printStackTrace();
  148. }
  149. }
  150. /**
  151. * Initializes the JPlag stub, by installing an all-trusting trust manager
  152. * for the SSL connection to the server, instantiating a stub object and
  153. * setting username and password
  154. *
  155. * @return True, if username and password have been set
  156. */
  157. private boolean initJPlagStub() {
  158. /*
  159. * Create a trust manager that does not validate certificate chains
  160. */
  161. TrustManager[] trustAllCerts = new TrustManager[]{
  162. new X509TrustManager() {
  163. public X509Certificate[] getAcceptedIssuers() {
  164. return null;
  165. }
  166. public void checkClientTrusted(X509Certificate[] certs,
  167. String authType) {
  168. }
  169. public void checkServerTrusted(X509Certificate[] certs,
  170. String authType) {
  171. }
  172. }
  173. };
  174. /*
  175. * Install the all-trusting trust manager
  176. */
  177. try {
  178. SSLContext sc = SSLContext.getInstance("SSL");
  179. sc.init(null, trustAllCerts, new java.security.SecureRandom());
  180. HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
  181. } catch (Exception e) {
  182. System.out.println("Warning: Unable to install all-trusting trust "
  183. + "manager! SSL connection may not work!");
  184. }
  185. /*
  186. * Get JPlag client stub
  187. */
  188. stub = (JPlagTyp_Stub) (new JPlagService_Impl()
  189. .getJPlagServicePort());
  190. /*
  191. * Search for the JPlagClientAccessHandler in the handler chain
  192. */
  193. HandlerChain handlerchain = stub._getHandlerChain();
  194. Iterator handlers = handlerchain.iterator();
  195. JPlagClientAccessHandler accessHandler = null;
  196. while (handlers.hasNext()) {
  197. Handler handler = (Handler) handlers.next();
  198. if (handler instanceof JPlagClientAccessHandler) {
  199. accessHandler = (JPlagClientAccessHandler) handler;
  200. break;
  201. }
  202. }
  203. if (accessHandler == null) {
  204. System.out.println("Unable to find access handler! Cannot set "
  205. + "username and password!");
  206. return false;
  207. }
  208. /*
  209. * Initialize access handler
  210. */
  211. accessHandler.setUserPassObjects(username, password);
  212. return true;
  213. }
  214. /**
  215. * Accepts directories and files with one of the given suffixes
  216. */
  217. private class RecursiveFilenameFilter implements FilenameFilter {
  218. public boolean accept(File dir, String name) {
  219. if (new File(dir, name).isDirectory()) return true;
  220. for (int i = 0; i < suffixes.length; i++) {
  221. if (name.endsWith(suffixes[i]))
  222. return true;
  223. }
  224. return false;
  225. }
  226. }
  227. /**
  228. * Only accepts files with one of the given suffixes
  229. */
  230. private class NonRecursiveFilenameFilter implements FilenameFilter {
  231. public boolean accept(@SuppressWarnings("unused") File dir,
  232. String name) {
  233. for (int i = 0; i < suffixes.length; i++) {
  234. if (name.endsWith(suffixes[i]))
  235. return true;
  236. }
  237. return false;
  238. }
  239. }
  240. /**
  241. * Collects all valid files inside a directory. If subdirFileFilter also
  242. * accepts directories, subdirectories are included in the search
  243. *
  244. * @param colfiles Vector receiving the found files
  245. * @param dir The directory which will be searched
  246. */
  247. private void collectInDir(Vector<File> colfiles, File dir) {
  248. try {
  249. System.out.println(dir.getCanonicalPath());
  250. } catch (IOException e) {
  251. e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
  252. }
  253. if (!dir.exists()) return;
  254. File[] files = dir.listFiles(subdirFileFilter);
  255. for (int i = 0; i < files.length; i++) {
  256. System.out.println(files[i].getName());
  257. if (files[i].isDirectory()) {
  258. collectInDir(colfiles, files[i]);
  259. } else colfiles.add(files[i]);
  260. }
  261. }
  262. /**
  263. * Collects all valid files according to the set options
  264. *
  265. * @return A Vector object of all valid files
  266. */
  267. private Vector<File> collectFiles() {
  268. Vector<File> colfiles = new Vector<File>();
  269. File[] files = new File(option.getOriginalDir()).listFiles(
  270. new RecursiveFilenameFilter());
  271. if (files == null) {
  272. System.out.println("\"" + option.getOriginalDir()
  273. + "\" is not a directory or an I/O error occurred!");
  274. return null;
  275. }
  276. if (option.isReadSubdirs())
  277. subdirFileFilter = new RecursiveFilenameFilter();
  278. else
  279. subdirFileFilter = new NonRecursiveFilenameFilter();
  280. for (int i = 0; i < files.length; i++) {
  281. if (files[i].isDirectory()) {
  282. if (option.getPathToFiles() != null)
  283. collectInDir(colfiles, new File(files[i],
  284. option.getPathToFiles()));
  285. else
  286. collectInDir(colfiles, files[i]);
  287. } else colfiles.add(files[i]);
  288. }
  289. if (colfiles.size() <= 1) {
  290. System.out.println("\"" + option.getOriginalDir()
  291. + "\" didn't contain at least two files\n"
  292. + "suitable for the specified options!");
  293. return null;
  294. }
  295. return colfiles;
  296. }
  297. /**
  298. * Creates a temporary zip file containing all files specified by the Option
  299. * object and sends it to the server in 80 kB parts
  300. *
  301. * @return The submissionID string or null, if there was an error
  302. */
  303. private String sendSubmission() {
  304. Vector<File> submissionFiles = collectFiles();
  305. if (submissionFiles == null) return null;
  306. File zipfile = null;
  307. FileInputStream input = null;
  308. String submissionID = null;
  309. try {
  310. zipfile = File.createTempFile("jplagtmp", ".zip");
  311. ZipUtil.zipFilesTo(submissionFiles, option.getOriginalDir(),
  312. zipfile);
  313. input = new FileInputStream(zipfile);
  314. int filesize = (int) zipfile.length();
  315. int sentsize = 0;
  316. int partsize = (filesize < 81920) ? filesize : 81920;
  317. byte[] data = new byte[partsize];
  318. input.read(data);
  319. initProgressBar(filesize);
  320. StartSubmissionUploadParams params =
  321. new StartSubmissionUploadParams(option, filesize, data);
  322. submissionID = stub.startSubmissionUpload(params);
  323. sentsize += partsize;
  324. while (sentsize < filesize - partsize) {
  325. setProgressBarValue(sentsize);
  326. input.read(data);
  327. stub.continueSubmissionUpload(data);
  328. sentsize += partsize;
  329. }
  330. if (sentsize != filesize) { // transfer last part
  331. setProgressBarValue(sentsize);
  332. data = new byte[filesize - sentsize];
  333. input.read(data);
  334. stub.continueSubmissionUpload(data);
  335. sentsize = filesize;
  336. }
  337. setProgressBarValue(sentsize);
  338. input.close();
  339. zipfile.delete();
  340. } catch (Exception e) {
  341. System.out.println();
  342. checkException(e);
  343. if (input != null) {
  344. try {
  345. input.close();
  346. } catch (Exception ex) {
  347. }
  348. }
  349. if (zipfile != null) zipfile.delete();
  350. return null;
  351. }
  352. return submissionID;
  353. }
  354. /**
  355. * Retrieves the status of the given submission
  356. *
  357. * @param submissionID submission ID identifying the submission
  358. * @return The according status object or null on error
  359. */
  360. private Status getStatus(String submissionID) {
  361. Status status;
  362. try {
  363. status = stub.getStatus(submissionID);
  364. } catch (Exception e) {
  365. checkException(e);
  366. return null;
  367. }
  368. return status;
  369. }
  370. /**
  371. * Waits until either the submission has been finished or an error occurred
  372. *
  373. * @param submissionID String identifying the submission
  374. * @return True, if the submission has been completed successfully
  375. */
  376. private boolean waitForResult(String submissionID) {
  377. Status status;
  378. try {
  379. while (true) {
  380. status = stub.getStatus(submissionID);
  381. /*
  382. * Here you could print out more details about the status of
  383. * the submission, but it's left out here...
  384. */
  385. if (status.getState() >= JPLAG_DONE) break;
  386. Thread.sleep(10000); // wait 10 seconds
  387. System.out.print("."); // tell user something's happening
  388. }
  389. if (status.getState() >= JPLAG_ERROR) {
  390. /*
  391. * An error occurred: Print out error message and acknowledge
  392. * error by cancelling the submission
  393. */
  394. System.out.println("\nSome error occurred: "
  395. + status.getReport());
  396. stub.cancelSubmission(submissionID);
  397. return false;
  398. }
  399. } catch (Exception e) {
  400. checkException(e);
  401. return false;
  402. }
  403. return true;
  404. }
  405. /**
  406. * Downloads and unzips the result
  407. *
  408. * @param submissionID The submission id String
  409. * @return True on success
  410. */
  411. private boolean receiveResult(String submissionID) {
  412. File zipfile = null;
  413. FileOutputStream output = null;
  414. try {
  415. File resultDir = new File(resultDirName);
  416. if (!resultDir.exists()) resultDir.mkdirs();
  417. zipfile = File.createTempFile("jplagtmpresult", ".zip");
  418. output = new FileOutputStream(zipfile);
  419. StartResultDownloadData srdd = stub.startResultDownload(
  420. submissionID);
  421. int filesize = srdd.getFilesize();
  422. int loadedsize = srdd.getData().length;
  423. initProgressBar(srdd.getFilesize());
  424. output.write(srdd.getData());
  425. setProgressBarValue(loadedsize);
  426. while (loadedsize < filesize) {
  427. byte[] data = stub.continueResultDownload(0);
  428. output.write(data);
  429. loadedsize += data.length;
  430. setProgressBarValue(loadedsize);
  431. }
  432. output.close();
  433. /*
  434. * Unzip result archive and delete the zip file
  435. */
  436. ZipUtil.unzip(zipfile, resultDir);
  437. zipfile.delete();
  438. } catch (Exception e) {
  439. if (output != null) {
  440. try {
  441. output.close();
  442. } catch (Exception ex) {
  443. }
  444. }
  445. if (zipfile != null) zipfile.delete();
  446. checkException(e);
  447. return false;
  448. }
  449. return true;
  450. }
  451. /**
  452. * Cancels the submission identified by submissionID
  453. *
  454. * @param submissionID The submission id string
  455. * @return True on success
  456. */
  457. private boolean cancelSubmission(String submissionID) {
  458. try {
  459. stub.cancelSubmission(submissionID);
  460. } catch (Exception e) {
  461. checkException(e);
  462. return false;
  463. }
  464. return true;
  465. }
  466. /**
  467. * Checks the current options for validity using the information provided
  468. * by the ServerInfo object and fills remaining empty fields with defaults.
  469. * If "-l ?" or "-cl ?" is used, a list of valid languages respectively
  470. * country languages is printed and false is returned.
  471. *
  472. * @param info ServerInfo object
  473. * @return True, if all options are legal
  474. */
  475. private boolean checkOptions(ServerInfo info) {
  476. LanguageInfo[] languages = info.getLanguageInfos();
  477. String[] countryLangs = info.getCountryLanguages();
  478. int i;
  479. if (option.getLanguage() == null) {
  480. i = 0;
  481. option.setLanguage(languages[0].getName());
  482. System.out.println("Using default language: "
  483. + languages[0].getName());
  484. } else {
  485. for (i = 0; i < languages.length; i++) {
  486. if (option.getLanguage().equals(languages[i].getName())) break;
  487. }
  488. if (i == languages.length) {
  489. if (!option.getLanguage().equals("?"))
  490. System.out.println("Unknown language: \""
  491. + option.getLanguage() + "\"");
  492. System.out.println("\nAvailable languages:");
  493. for (i = 0; i < languages.length; i++) {
  494. System.out.println(" - \"" + languages[i].getName()
  495. + "\"" + (i == 0 ? " (default language)\n" : "\n")
  496. + " default minimum match length = "
  497. + languages[i].getDefMinMatchLen()
  498. + "\n default suffixes: "
  499. + arrayToString(languages[i].getSuffixes()));
  500. }
  501. return false;
  502. }
  503. }
  504. if (suffixes == null) {
  505. suffixes = languages[i].getSuffixes();
  506. System.out.println("Using default suffixes: "
  507. + arrayToString(suffixes));
  508. }
  509. if (option.getTitle() == null)
  510. option.setTitle("submission-"
  511. + new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
  512. if (option.getCountryLang() == null)
  513. option.setCountryLang("en");
  514. else {
  515. for (i = 0; i < countryLangs.length; i++) {
  516. if (option.getCountryLang().equals(countryLangs[i])) break;
  517. }
  518. if (i == countryLangs.length) {
  519. if (!option.getCountryLang().equals("?"))
  520. System.out.println("Unknown country language: \""
  521. + option.getCountryLang() + "\"");
  522. System.out.println("\nAvailable country languages:");
  523. for (i = 0; i < countryLangs.length; i++) {
  524. System.out.println(" - \"" + countryLangs[i]
  525. + (i == 0 ? "\" (default)" : "\""));
  526. }
  527. return false;
  528. }
  529. }
  530. return true;
  531. }
  532. /**
  533. * Parses the arguments and sets the appropriate attributes
  534. *
  535. * @param args Array of argument strings
  536. * @return True, if no error was noticed like missing login data
  537. */
  538. private boolean parseArguments(String[] args) {
  539. boolean requestDetails = false;
  540. for (int i = 0; i < args.length; i++) {
  541. if (args[i].equals("-user") && i + 1 < args.length) {
  542. i++;
  543. username = args[i];
  544. } else if (args[i].equals("-pass") && i + 1 < args.length) {
  545. i++;
  546. password = args[i];
  547. } else if (args[i].equals("-l") && i + 1 < args.length) {
  548. i++;
  549. option.setLanguage(args[i]);
  550. if (args[i].equals("?")) requestDetails = true;
  551. } else if (args[i].equals("-cl") && i + 1 < args.length) {
  552. i++;
  553. option.setCountryLang(args[i]);
  554. if (args[i].equals("?")) requestDetails = true;
  555. } else if (args[i].equals("-s")) {
  556. option.setReadSubdirs(true);
  557. } else if (args[i].equals("-S") && i + 1 < args.length) {
  558. i++;
  559. option.setPathToFiles(args[i]);
  560. } else if (args[i].equals("-p") && i + 1 < args.length) {
  561. i++;
  562. suffixes = args[i].split(",");
  563. option.setSuffixes(suffixes);
  564. } else if (args[i].equals("-t") && i + 1 < args.length) {
  565. i++;
  566. try {
  567. option.setMinimumMatchLength(Integer.parseInt(args[i]));
  568. } catch (NumberFormatException e) {
  569. System.out.println("Illegal minimum match length: "
  570. + args[i] + "\nMust be an integer!");
  571. return false;
  572. }
  573. } else if (args[i].equals("-m") && i + 1 < args.length) {
  574. i++;
  575. option.setStoreMatches(args[i]);
  576. } else if (args[i].equals("-bc") && i + 1 < args.length) {
  577. i++;
  578. option.setBasecodeDir(args[i]);
  579. } else if (args[i].equals("-r") && i + 1 < args.length) {
  580. i++;
  581. resultDirName = args[i];
  582. } else if (args[i].equals("-title") && i + 1 < args.length) {
  583. i++;
  584. option.setTitle(args[i]);
  585. } else if (args[i].equals("-list")) {
  586. listSubmissions = true;
  587. } else if (args[i].equals("-download")) {
  588. if (i + 1 < args.length && Character.isDigit(args[i + 1].charAt(0))) {
  589. // isDigit is true => positive value
  590. i++;
  591. try {
  592. downloadResultNumber = Integer.parseInt(args[i]);
  593. } catch (NumberFormatException e) {
  594. System.out.println("Illegal download number: "
  595. + args[i] + "\nMust be an positive integer!");
  596. return false;
  597. }
  598. } else downloadResultNumber = 1;
  599. } else if (args[i].equals("-cancel")) {
  600. if (i + 1 < args.length && Character.isDigit(args[i + 1].charAt(0))) {
  601. // isDigit is true => positive value
  602. i++;
  603. try {
  604. cancelSubmissionNumber = Integer.parseInt(args[i]);
  605. } catch (NumberFormatException e) {
  606. System.out.println("Illegal cancel number: "
  607. + args[i] + "\nMust be an positive integer!");
  608. return false;
  609. }
  610. } else cancelSubmissionNumber = 1;
  611. } else if (args[i].startsWith("-")) {
  612. System.out.println("Unknown option: " + args[i]);
  613. return false;
  614. } else {
  615. if (option.getOriginalDir() != null) {
  616. System.out.println("The rootdir has already been defined "
  617. + "as \"" + option.getOriginalDir() + "\"!");
  618. return false;
  619. }
  620. option.setOriginalDir(args[i]);
  621. }
  622. }
  623. boolean valid = true;
  624. if (username == null) {
  625. System.out.println("Username is missing!");
  626. valid = false;
  627. }
  628. if (password == null) {
  629. System.out.println("Password is missing!");
  630. valid = false;
  631. }
  632. if (!requestDetails && !listSubmissions && downloadResultNumber == 0
  633. && cancelSubmissionNumber == 0
  634. && option.getOriginalDir() == null) {
  635. System.out.println("You must specify either a \"root-dir\", the "
  636. + "\"-list\", the \"-download\"\nor the \"-cancel\" option!");
  637. valid = false;
  638. }
  639. return valid;
  640. }
  641. /**
  642. * Initializes a text progress bar
  643. */
  644. public void initProgressBar(int max) {
  645. progressMax = max;
  646. progressPos = 0;
  647. System.out.println(
  648. "0%----------+----------50%-----------+--------100%");
  649. }
  650. /**
  651. * Sets the current value of the progress bar updating the current position
  652. * The progress may only increase, not decrease!
  653. */
  654. public void setProgressBarValue(int val) {
  655. int pos = (val * 50) / progressMax;
  656. if (pos <= progressPos) return;
  657. System.out.print("##################################################"
  658. .substring(progressPos, pos));
  659. progressPos = pos;
  660. }
  661. /**
  662. * Prints out how to use the program
  663. */
  664. public static void printUsage() {
  665. System.out.println(
  666. "\nUsage: ExampleClient [options] (<root-dir> | -list | -download [<n>]\n"
  667. + " | -cancel [<n>])\n"
  668. + "<root-dir> The directory which contains all programs\n"
  669. + "Options are:\n"
  670. + " -user <username> Sets the username (required).\n"
  671. + " -pass <password> Sets the password (required).\n"
  672. + " -l <language> (Language) Programming language.\n"
  673. + " (\"-l ?\" for supported and default languages.\n"
  674. + " Also lists default suffixes and minimum match length)\n"
  675. + " -S <dir> Look in directories <root-dir>/*/<dir> for programs.\n"
  676. + " (default: <root-dir>/*)\n"
  677. + " -s (Subdirs) Look at files in subdirs, too. (default: disabled)\n"
  678. + " -p <suffixes> <suffixes> is a comma-separated list of filename suffixes\n"
  679. + " to be included. (default: language specific)\n"
  680. + " -t <n> (Token) Set the minimum match length in tokens.\n"
  681. + " A smaller <n> increases the sensitivity of the comparison.\n"
  682. + " -m <n> (Matches) Number of matches that will be saved. (default:20)\n"
  683. + " -m <p>% Saves all matches with more than <p>% average similitarity.\n"
  684. + " -bc <dir> Name of the directory containing the basecode\n"
  685. + " (common framework).\n"
  686. + " -r <dir> (Result) Name of directory where the result pages will\n"
  687. + " be stored. (default: result)\n"
  688. + " -title <title> Title of this submission (default: submission-<date>)\n"
  689. + " -cl <locale> (Country language) Language the result files will\n"
  690. + " be written in.\n"
  691. + " (\"-cl ?\" for supported country languages and default)\n"
  692. + " -list Lists all submissions on the server belonging to the user.\n"
  693. + " -download [<n>] Downloads the <n>-th submission from server.\n"
  694. + " The <n>-th submission must be \"done\".\n"
  695. + " All non required options except \"-r <dir>\" will be ignored.\n"
  696. + " -cancel [<n>] Cancels the <n>-th submission on server.\n"
  697. + " All non required options will be ignored.\n");
  698. }
  699. /**
  700. * Concatenates the string representations of objects in an array
  701. *
  702. * @param array Object array
  703. * @return Comma-separated list of string representations of those objects
  704. */
  705. private String arrayToString(Object[] array) {
  706. String str = "";
  707. for (int i = 0; i < array.length; i++) {
  708. str += array[i].toString();
  709. if (i != array.length - 1) str += ",";
  710. }
  711. return str;
  712. }
  713. /**
  714. * The main routine
  715. *
  716. * @param args Array of command line parameters
  717. */
  718. public void run(String[] args) {
  719. if (args.length == 0 || !parseArguments(args)) {
  720. printUsage();
  721. return;
  722. }
  723. if (!initJPlagStub()) {
  724. System.out.println("Unable to initialize JPlag stub!");
  725. return;
  726. }
  727. /*
  728. * Get a ServerInfo object
  729. */
  730. ServerInfo info;
  731. try {
  732. info = stub.getServerInfo();
  733. } catch (Exception e) {
  734. checkException(e);
  735. return;
  736. }
  737. /*
  738. * Check for submissions on server by looking at submissions field
  739. * in the ServerInfo object
  740. */
  741. Submission[] subs = info.getSubmissions();
  742. if (subs.length > 0) {
  743. System.out.println("\nSubmissions on server with states:\n");
  744. for (int i = 0; i < subs.length; i++) {
  745. System.out.println(" " + (i + 1) + ". \"" + subs[i].getTitle()
  746. + "\" on " + subs[i].getDate());
  747. String stateString = "";
  748. switch (subs[i].getLastState()) {
  749. case JPLAG_UPLOADING: // can not occur in this application
  750. stateString = "uploading";
  751. break;
  752. case JPLAG_INQUEUE:
  753. stateString = "in queue";
  754. break;
  755. case JPLAG_PARSING:
  756. stateString = "parsing";
  757. break;
  758. case JPLAG_COMPARING:
  759. stateString = "comparing";
  760. break;
  761. case JPLAG_GENRESULT:
  762. stateString = "generating result files";
  763. break;
  764. case JPLAG_PACKRESULT:
  765. stateString = "packing result files";
  766. break;
  767. case JPLAG_DONE:
  768. stateString = "done";
  769. break;
  770. default: {
  771. // an error occurred, so get more details
  772. Status status = getStatus(subs[i].getSubmissionID());
  773. if (status == null)
  774. stateString = "unable to retrieve status";
  775. else
  776. stateString = status.getReport();
  777. }
  778. }
  779. System.out.println(" (" + stateString + ")");
  780. }
  781. if (listSubmissions) return;
  782. /*
  783. * If "-download" is used, download the n-th submission
  784. */
  785. if (downloadResultNumber != 0) {
  786. if (downloadResultNumber > subs.length) {
  787. System.out.println("Illegal download number!\n"
  788. + "There are only " + subs.length + " submissions!");
  789. return;
  790. }
  791. Submission sub = subs[downloadResultNumber - 1];
  792. if (sub.getLastState() != 300) {
  793. System.out.println("Illegal download number!\n"
  794. + "You can only download results for successfully"
  795. + " finished submissions!");
  796. return;
  797. }
  798. System.out.print("Downloading \"" + sub.getTitle()
  799. + "\"...");
  800. if (!receiveResult(sub.getSubmissionID())) return;
  801. System.out.println(" completed.\nThe result files are available"
  802. + " in \"" + resultDirName + "\"");
  803. return;
  804. }
  805. /*
  806. * If "-cancel" is used, cancel the n-th submission
  807. */
  808. if (cancelSubmissionNumber != 0) {
  809. if (cancelSubmissionNumber > subs.length) {
  810. System.out.println("Illegal cancel number!\n"
  811. + "There are only " + subs.length + " submissions!");
  812. return;
  813. }
  814. Submission sub = subs[cancelSubmissionNumber - 1];
  815. System.out.print("Cancelling \"" + sub.getTitle()
  816. + "\"...");
  817. if (!cancelSubmission(sub.getSubmissionID())) return;
  818. System.out.println(" completed.\n");
  819. return;
  820. }
  821. } else if (downloadResultNumber != 0 || cancelSubmissionNumber != 0
  822. || listSubmissions) {
  823. System.out.println("\nCurrently there are no submissions on the "
  824. + "server for this user!");
  825. return;
  826. }
  827. if (!checkOptions(info)) return;
  828. System.out.println("\nSending files...");
  829. String submissionID = sendSubmission();
  830. if (submissionID == null) return;
  831. System.out.print("\n\nWaiting for result...");
  832. if (!waitForResult(submissionID)) return;
  833. System.out.println(" result available.\n\nDownloading...");
  834. if (!receiveResult(submissionID)) return;
  835. System.out.println("\n\nThe result files are available in \""
  836. + resultDirName + "\"");
  837. }
  838. public static void main(String[] args) {
  839. new ExampleClient().run(args);
  840. }
  841. }