PageRenderTime 24ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/src/hampi/HampiServer.java

http://hampi.googlecode.com/
Java | 408 lines | 253 code | 59 blank | 96 comment | 17 complexity | 57ea715b91ff64e3ae523e5698cd9c6a MD5 | raw file
  1. package hampi;
  2. import java.io.*;
  3. import java.net.*;
  4. import java.util.*;
  5. /**
  6. * This runs Hampi as a server. Clients connect to it and pass file names. <br>
  7. * The server terminates when the input line is "SHUTDOWN".<br>
  8. * <br>
  9. * XXX: this is not secure because we read files from the disk (whatever the
  10. * client says).
  11. */
  12. public final class HampiServer{
  13. public static final String HAMPISERVER_RUNNING = ".hampiserverRunning";
  14. public static void main(String[] args) throws Exception{
  15. if (args.length != 1){
  16. System.out.println("usage: HampiServer port");
  17. System.out.println("send \"SHUTDOWN\" to shut down (e.g., echo SHUTDOWN | nc localhost port)");
  18. return;
  19. }
  20. // create socket
  21. int port = Integer.parseInt(args[0]);
  22. ServerSocket serverSocket = new ServerSocket(port, 1, InetAddress.getByName("localhost"));
  23. System.err.println(new Date() + " started Hampi server on port " + port);
  24. //create file to indicate that server is running. NOTE this is lame
  25. File serverRunning = new File(HAMPISERVER_RUNNING);
  26. boolean lockCreated = serverRunning.createNewFile();
  27. if (lockCreated == false)
  28. throw new IllegalStateException("Remove the " + HAMPISERVER_RUNNING + " file");
  29. serverRunning.deleteOnExit();
  30. // repeatedly wait for connections, and process
  31. while (true){
  32. // a "blocking" call which waits until a connection is requested
  33. Socket clientSocket = serverSocket.accept();
  34. System.out.println(new Date() + " accepted connection");
  35. // open up IO streams
  36. In in = new In(clientSocket);
  37. Out out = new Out(clientSocket);
  38. // waits for data and reads it in until connection dies
  39. // readLine() blocks until the server receives a new line from client
  40. String fname = in.readLine();
  41. if (fname.equals("SHUTDOWN")){
  42. Date now = new Date();
  43. System.out.println(now + " Hampi server shutting down on port " + port);
  44. out.println(now + " Hampi server shutting down on port " + port);
  45. out.close();
  46. in.close();
  47. clientSocket.close();
  48. return;
  49. }
  50. System.out.println("solving: " + fname);
  51. PrintStream oldOut = System.out;
  52. try{
  53. OutputStream os = new ByteArrayOutputStream();
  54. System.setOut(new PrintStream(os));
  55. File file = new File(fname);
  56. if (file.exists()){
  57. Hampi.run(false, false, new FileInputStream(file));
  58. out.println(os.toString());
  59. }else{
  60. out.println("ERROR file " + fname + " does not exist");
  61. oldOut.println("ERROR file " + fname + " does not exist");
  62. }
  63. }catch (HampiResultException e){
  64. oldOut.println(e.getMessage());
  65. out.println(e.getMessage());
  66. }catch (ThreadDeath t){
  67. oldOut.println("ERROR server dies " + t);
  68. throw t;
  69. }catch (Throwable t){
  70. out.println("ERROR " + t.getMessage());
  71. oldOut.println("ERROR " + t.getMessage());
  72. }finally{
  73. System.setOut(oldOut);
  74. // close IO streams, then socket
  75. System.out.println(new Date() + " closing connection");
  76. out.close();
  77. in.close();
  78. clientSocket.close();
  79. }
  80. }
  81. }
  82. }
  83. /**
  84. * <i>Input</i>. This class provides methods for reading strings and numbers
  85. * from standard input, file input, URL, and socket.
  86. * <p>
  87. * The Locale used is: language = English, country = US. This is consistent with
  88. * the formatting conventions with Java floating-point literals, command-line
  89. * arguments (via <tt>Double.parseDouble()</tt>) and standard output (via
  90. * <tt>System.out.print()</tt>). It ensures that standard input works the number
  91. * formatting used in the textbook.
  92. * <p>
  93. * For additional documentation, see <a
  94. * href="http://www.cs.princeton.edu/introcs/31datatype">Section 3.1</a> of
  95. * <i>Introduction to Programming in Java: An Interdisciplinary Approach</i> by
  96. * Robert Sedgewick and Kevin Wayne.
  97. */
  98. final class In{
  99. private Scanner scanner;
  100. // assume Unicode UTF-8 encoding
  101. //private String charsetName = "UTF-8";
  102. private final String charsetName = "ISO-8859-1";
  103. // assume language = English, country = US for consistency with System.out.
  104. private final Locale usLocale = new Locale("en", "US");
  105. /**
  106. * Create an input stream for standard input.
  107. */
  108. public In(){
  109. scanner = new Scanner(System.in, charsetName);
  110. scanner.useLocale(usLocale);
  111. }
  112. /**
  113. * Create an input stream from a socket.
  114. */
  115. public In(Socket socket){
  116. try{
  117. InputStream is = socket.getInputStream();
  118. scanner = new Scanner(is, charsetName);
  119. scanner.useLocale(usLocale);
  120. }catch (IOException ioe){
  121. System.err.println("Could not open " + socket);
  122. }
  123. }
  124. /**
  125. * Create an input stream from a URL.
  126. */
  127. public In(URL url){
  128. try{
  129. URLConnection site = url.openConnection();
  130. InputStream is = site.getInputStream();
  131. scanner = new Scanner(is, charsetName);
  132. scanner.useLocale(usLocale);
  133. }catch (IOException ioe){
  134. System.err.println("Could not open " + url);
  135. }
  136. }
  137. /**
  138. * Create an input stream from a file or web page.
  139. */
  140. public In(String s){
  141. try{
  142. // first try to read file from local file system
  143. File file = new File(s);
  144. if (file.exists()){
  145. scanner = new Scanner(file, charsetName);
  146. scanner.useLocale(usLocale);
  147. return;
  148. }
  149. // next try for files included in jar
  150. URL url = getClass().getResource(s);
  151. // or URL from web
  152. if (url == null){
  153. url = new URL(s);
  154. }
  155. URLConnection site = url.openConnection();
  156. InputStream is = site.getInputStream();
  157. scanner = new Scanner(is, charsetName);
  158. scanner.useLocale(usLocale);
  159. }catch (IOException ioe){
  160. System.err.println("Could not open " + s);
  161. }
  162. }
  163. /**
  164. * Does the input stream exist?
  165. */
  166. public boolean exists(){
  167. return scanner != null;
  168. }
  169. /**
  170. * Is the input stream empty?
  171. */
  172. public boolean isEmpty(){
  173. return !scanner.hasNext();
  174. }
  175. /**
  176. * Read and return the next line or null if there is no next line.
  177. */
  178. public String readLine(){
  179. if (!scanner.hasNextLine())
  180. return null;
  181. return scanner.nextLine();
  182. }
  183. /**
  184. * Read and return the next character.
  185. */
  186. public char readChar(){
  187. // (?s) for DOTALL mode so . matches any character, including a line termination character
  188. // 1 says look only one character ahead
  189. // consider precompiling the pattern
  190. String s = scanner.findWithinHorizon("(?s).", 1);
  191. return s.charAt(0);
  192. }
  193. // return rest of input as string
  194. /**
  195. * Read and return the remainder of the input as a string.
  196. */
  197. public String readAll(){
  198. if (!scanner.hasNextLine())
  199. return null;
  200. // reference: http://weblogs.java.net/blog/pat/archive/2004/10/stupid_scanner_1.html
  201. return scanner.useDelimiter("\\A").next();
  202. }
  203. /**
  204. * Return the next string from the input stream.
  205. */
  206. public String readString(){
  207. return scanner.next();
  208. }
  209. /**
  210. * Return the next int from the input stream.
  211. */
  212. public int readInt(){
  213. return scanner.nextInt();
  214. }
  215. /**
  216. * Return the next double from the input stream.
  217. */
  218. public double readDouble(){
  219. return scanner.nextDouble();
  220. }
  221. /**
  222. * Return the next float from the input stream.
  223. */
  224. public double readFloat(){
  225. return scanner.nextFloat();
  226. }
  227. /**
  228. * Return the next long from the input stream.
  229. */
  230. public long readLong(){
  231. return scanner.nextLong();
  232. }
  233. /**
  234. * Return the next byte from the input stream.
  235. */
  236. public byte readByte(){
  237. return scanner.nextByte();
  238. }
  239. /**
  240. * Return the next boolean from the input stream, allowing "true" or "1" for
  241. * true and "false" or "0" for false.
  242. */
  243. public boolean readBoolean(){
  244. String s = readString();
  245. if (s.equalsIgnoreCase("true"))
  246. return true;
  247. if (s.equalsIgnoreCase("false"))
  248. return false;
  249. if (s.equals("1"))
  250. return true;
  251. if (s.equals("0"))
  252. return false;
  253. throw new java.util.InputMismatchException();
  254. }
  255. /**
  256. * Close the input stream.
  257. */
  258. public void close(){
  259. scanner.close();
  260. }
  261. }
  262. class Out{
  263. private PrintWriter out;
  264. // for stdout
  265. public Out(OutputStream os){
  266. out = new PrintWriter(os, true);
  267. }
  268. public Out(){
  269. this(System.out);
  270. }
  271. // for Socket output
  272. public Out(Socket socket){
  273. try{
  274. out = new PrintWriter(socket.getOutputStream(), true);
  275. }catch (IOException ioe){
  276. ioe.printStackTrace();
  277. }
  278. }
  279. // for file output
  280. public Out(String s){
  281. try{
  282. out = new PrintWriter(new FileOutputStream(s), true);
  283. }catch (IOException ioe){
  284. ioe.printStackTrace();
  285. }
  286. }
  287. public void close(){
  288. out.close();
  289. }
  290. public void println(){
  291. out.println();
  292. out.flush();
  293. }
  294. public void println(Object x){
  295. out.println(x);
  296. out.flush();
  297. }
  298. public void println(boolean x){
  299. out.println(x);
  300. out.flush();
  301. }
  302. public void println(char x){
  303. out.println(x);
  304. out.flush();
  305. }
  306. public void println(double x){
  307. out.println(x);
  308. }
  309. public void println(float x){
  310. out.println(x);
  311. }
  312. public void println(int x){
  313. out.println(x);
  314. }
  315. public void println(long x){
  316. out.println(x);
  317. }
  318. public void print(){
  319. out.flush();
  320. }
  321. public void print(Object x){
  322. out.print(x);
  323. out.flush();
  324. }
  325. public void print(boolean x){
  326. out.print(x);
  327. out.flush();
  328. }
  329. public void print(char x){
  330. out.print(x);
  331. out.flush();
  332. }
  333. public void print(double x){
  334. out.print(x);
  335. out.flush();
  336. }
  337. public void print(float x){
  338. out.print(x);
  339. out.flush();
  340. }
  341. public void print(int x){
  342. out.print(x);
  343. out.flush();
  344. }
  345. public void print(long x){
  346. out.print(x);
  347. out.flush();
  348. }
  349. }