From 108df33133e695c103787eea7ae6ec15159af0d6 Mon Sep 17 00:00:00 2001 From: Oleg Lontsov Date: Wed, 21 Dec 2011 01:01:13 +0400 Subject: [PATCH 1/3] Release. Perhaps. --- .../ru/hh/school/stdlib/ClientHandler.java | 59 +++++++++++++++++++ .../java/ru/hh/school/stdlib/Launcher.java | 9 +-- src/main/java/ru/hh/school/stdlib/Server.java | 26 ++++++-- .../ru/hh/school/stdlib/Substitutor3000.java | 45 +++++++++++++- .../java/ru/hh/school/stdlib/GetPutTest.java | 56 ++++++++++++++++++ .../ru/hh/school/stdlib/RecursionTest.java | 43 ++++++++++++++ .../ru/hh/school/stdlib/RecursiveGet.java | 43 ++++++++++++++ .../ru/hh/school/stdlib/SimpleGetTest.java | 2 +- 8 files changed, 271 insertions(+), 12 deletions(-) create mode 100644 src/main/java/ru/hh/school/stdlib/ClientHandler.java create mode 100644 src/test/java/ru/hh/school/stdlib/GetPutTest.java create mode 100644 src/test/java/ru/hh/school/stdlib/RecursionTest.java create mode 100644 src/test/java/ru/hh/school/stdlib/RecursiveGet.java diff --git a/src/main/java/ru/hh/school/stdlib/ClientHandler.java b/src/main/java/ru/hh/school/stdlib/ClientHandler.java new file mode 100644 index 0000000..240795c --- /dev/null +++ b/src/main/java/ru/hh/school/stdlib/ClientHandler.java @@ -0,0 +1,59 @@ +package ru.hh.school.stdlib; + +import java.io.IOException; +import java.io.PrintWriter; +import java.net.Socket; +import java.util.Scanner; + +public class ClientHandler implements Runnable{ + private Socket incoming; + private final Substitutor3000 sbst; + + + public ClientHandler(Socket i, Substitutor3000 sb) { + incoming = i; + sbst = sb; + } + + @Override + public void run() { + try{ + try { + Scanner in = new Scanner(incoming.getInputStream()); + PrintWriter out = new PrintWriter(incoming.getOutputStream()); + String line = in.nextLine().trim(); + String[] req = line.split(" ", 3); + int len = req.length; + if (req[0].equals("GET")) { + Thread.sleep(sbst.getSleepTime()); + if(len>=2){ + out.println("VALUE"); + out.println(sbst.get(req[1]));} + else out.println("GET syntax: GET key"); + } + else if ((req[0].equals("SET"))&&(req[1].equals("SLEEP"))) { + if(len==3) synchronized (sbst){sbst.setSleepTime(Long.valueOf(req[2]));} + else out.println("SET syntax: SET SLEEP sleeptime"); + } + else if (req[0].equals("PUT")){ + Thread.sleep(sbst.getSleepTime()); + if(len==3){ + sbst.put(req[1], req[2]); + out.println("OK"); + } + else out.println("PUT syntax: PUT key value"); + } + else out.println("Unsupported request! We accept GET, PUT or SET SLEEP here!"); + out.flush(); + } catch (InterruptedException e) { + e.printStackTrace(); + } finally{ + incoming.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + + } + +} diff --git a/src/main/java/ru/hh/school/stdlib/Launcher.java b/src/main/java/ru/hh/school/stdlib/Launcher.java index 1bee1a8..5ec5f98 100644 --- a/src/main/java/ru/hh/school/stdlib/Launcher.java +++ b/src/main/java/ru/hh/school/stdlib/Launcher.java @@ -11,19 +11,20 @@ public static void main(String[] args) throws IOException { if (args.length == 0) { host = "127.0.0.1"; port = 9129; - } else if (args.length == 3) { - host = args[1]; - port = Integer.parseInt(args[2]); + } else if (args.length == 2) { + host = args[0]; + port = Integer.parseInt(args[1]); } else { throw new IllegalArgumentException(); } } catch (Exception e) { System.err.printf("Usage: %s [host port]%n", args[0]); + for (String s: args) System.out.println(s); + e.printStackTrace(); System.exit(1); return; // попробуйте закомментировать этот return } InetSocketAddress addr = InetSocketAddress.createUnresolved(host, port); - new Server(addr).run(); } } diff --git a/src/main/java/ru/hh/school/stdlib/Server.java b/src/main/java/ru/hh/school/stdlib/Server.java index 8284c32..6e4abaf 100644 --- a/src/main/java/ru/hh/school/stdlib/Server.java +++ b/src/main/java/ru/hh/school/stdlib/Server.java @@ -2,17 +2,35 @@ import java.io.IOException; import java.net.InetSocketAddress; +import java.net.ServerSocket; +import java.net.Socket; public class Server { - public Server(InetSocketAddress addr) { - throw new UnsupportedOperationException(); + private ServerSocket s; + private Substitutor3000 sbst; + public Server(InetSocketAddress addr){ + try{ + s = new ServerSocket(addr.getPort()); + sbst = new Substitutor3000(); + } + catch(IOException e){ + System.err.println("There's an I/O problem: "); + e.printStackTrace(); + System.exit(1); + } } public void run() throws IOException { - throw new UnsupportedOperationException(); + System.out.printf("Server started on port %d%n", this.getPort()); + while(true){ + Socket incoming = s.accept(); + Runnable r = new ClientHandler(incoming, sbst); + Thread t = new Thread(r); + t.start(); + } } public int getPort() { - throw new UnsupportedOperationException(); + return s.getLocalPort(); } } diff --git a/src/main/java/ru/hh/school/stdlib/Substitutor3000.java b/src/main/java/ru/hh/school/stdlib/Substitutor3000.java index 728598c..dce8394 100644 --- a/src/main/java/ru/hh/school/stdlib/Substitutor3000.java +++ b/src/main/java/ru/hh/school/stdlib/Substitutor3000.java @@ -1,11 +1,50 @@ package ru.hh.school.stdlib; +import java.util.HashMap; +import java.util.HashSet; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + public class Substitutor3000 { - public void put(String key, String value) { - throw new UnsupportedOperationException(); + + private long sleepTime; + private HashMap storage; + private HashSet inProgress = new HashSet(); + private final String recursionPanicString = "Panic!!! Infinite recursion!!!"; + + public Substitutor3000() { + storage = new HashMap(); + } + + public synchronized void put(String key, String value) { + storage.put(key, value); } public String get(String key) { - throw new UnsupportedOperationException(); + if (inProgress.contains(key)) { + inProgress.clear(); + return recursionPanicString; + } + String out = storage.get(key); + if(out==null) return ""; + inProgress.add(key); + Pattern pattern = Pattern.compile("\\p{Sc}\\{(\\S+)\\}"); + Matcher matcher = pattern.matcher(out); + while (matcher.find()){ + String part = get(matcher.group(1)); + if(part==null){ + part=""; + } + else if (part.equals(recursionPanicString)) return part; + out = out.replace(matcher.group(0),part); + } + inProgress.remove(key); + return out; } + public long getSleepTime() { + return sleepTime; + } + public void setSleepTime(long sleepTime) { + this.sleepTime = sleepTime; + } } diff --git a/src/test/java/ru/hh/school/stdlib/GetPutTest.java b/src/test/java/ru/hh/school/stdlib/GetPutTest.java new file mode 100644 index 0000000..e94495d --- /dev/null +++ b/src/test/java/ru/hh/school/stdlib/GetPutTest.java @@ -0,0 +1,56 @@ +package ru.hh.school.stdlib; + +import org.junit.Assert; +import org.junit.Test; + +import java.io.*; +import java.net.Socket; + + +public class GetPutTest extends BaseFunctionalTest{ + @Test + public void getPut() throws IOException { + Socket s = connect(); + + Writer out = new PrintWriter(s.getOutputStream()); + BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream())); + out.append("PUT k1 one\n").flush(); + Assert.assertEquals("OK", in.readLine()); + + s = connect(); + out = new PrintWriter(s.getOutputStream()); + in = new BufferedReader(new InputStreamReader(s.getInputStream())); + out.append("GET k1\n").flush(); + Assert.assertEquals("VALUE", in.readLine()); + Assert.assertEquals("one", in.readLine()); + + s = connect(); + out = new PrintWriter(s.getOutputStream()); + in = new BufferedReader(new InputStreamReader(s.getInputStream())); + out.append("PUT keys ${k1} ${k2}\n").flush(); + Assert.assertEquals("OK", in.readLine()); + + s = connect(); + out = new PrintWriter(s.getOutputStream()); + in = new BufferedReader(new InputStreamReader(s.getInputStream())); + out.append("GET keys\n").flush(); + Assert.assertEquals("VALUE", in.readLine()); + Assert.assertEquals("one ", in.readLine()); + + s = connect(); + out = new PrintWriter(s.getOutputStream()); + in = new BufferedReader(new InputStreamReader(s.getInputStream())); + out.append("PUT k2 two\n").flush(); + Assert.assertEquals("OK", in.readLine()); + + s = connect(); + out = new PrintWriter(s.getOutputStream()); + in = new BufferedReader(new InputStreamReader(s.getInputStream())); + out.append("GET keys\n").flush(); + Assert.assertEquals("VALUE", in.readLine()); + Assert.assertEquals("one two", in.readLine()); + + s.close(); + } + +} diff --git a/src/test/java/ru/hh/school/stdlib/RecursionTest.java b/src/test/java/ru/hh/school/stdlib/RecursionTest.java new file mode 100644 index 0000000..930ae51 --- /dev/null +++ b/src/test/java/ru/hh/school/stdlib/RecursionTest.java @@ -0,0 +1,43 @@ +package ru.hh.school.stdlib; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.io.Writer; +import java.net.Socket; +import org.junit.Assert; +import org.junit.Test; + +public class RecursionTest extends BaseFunctionalTest { + //This one tests protection from infinite recursion + @Test + public void recursivePut() throws IOException { + Socket s = connect(); + Writer out = new PrintWriter(s.getOutputStream()); + BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream())); + out.append("PUT keys3 ${l1} ${l2}\n").flush(); + Assert.assertEquals("OK", in.readLine()); + + s = connect(); + out = new PrintWriter(s.getOutputStream()); + in = new BufferedReader(new InputStreamReader(s.getInputStream())); + out.append("PUT l2 two\n").flush(); + Assert.assertEquals("OK", in.readLine()); + + s = connect(); + out = new PrintWriter(s.getOutputStream()); + in = new BufferedReader(new InputStreamReader(s.getInputStream())); + out.append("PUT l1 ${k4} ${keys3}\n").flush(); + Assert.assertEquals("OK", in.readLine()); + + s = connect(); + out = new PrintWriter(s.getOutputStream()); + in = new BufferedReader(new InputStreamReader(s.getInputStream())); + out.append("GET keys3\n").flush(); + Assert.assertEquals("VALUE", in.readLine()); + Assert.assertEquals("Panic!!! Infinite recursion!!!", in.readLine()); + + s.close(); + } +} diff --git a/src/test/java/ru/hh/school/stdlib/RecursiveGet.java b/src/test/java/ru/hh/school/stdlib/RecursiveGet.java new file mode 100644 index 0000000..4927a4f --- /dev/null +++ b/src/test/java/ru/hh/school/stdlib/RecursiveGet.java @@ -0,0 +1,43 @@ +package ru.hh.school.stdlib; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.io.Writer; +import java.net.Socket; +import org.junit.Assert; +import org.junit.Test; + +public class RecursiveGet extends BaseFunctionalTest { + //This is not a test for infinite recursion protection. + @Test + public void recursiveGet() throws IOException { + Socket s = connect(); + Writer out = new PrintWriter(s.getOutputStream()); + BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream())); + out.append("PUT keys2 ${k5} ${k2}\n").flush(); + Assert.assertEquals("OK", in.readLine()); + + s = connect(); + out = new PrintWriter(s.getOutputStream()); + in = new BufferedReader(new InputStreamReader(s.getInputStream())); + out.append("PUT k4 two\n").flush(); + Assert.assertEquals("OK", in.readLine()); + + s = connect(); + out = new PrintWriter(s.getOutputStream()); + in = new BufferedReader(new InputStreamReader(s.getInputStream())); + out.append("PUT k5 k1 ${k4}\n").flush(); + Assert.assertEquals("OK", in.readLine()); + + s = connect(); + out = new PrintWriter(s.getOutputStream()); + in = new BufferedReader(new InputStreamReader(s.getInputStream())); + out.append("GET keys2\n").flush(); + Assert.assertEquals("VALUE", in.readLine()); + Assert.assertEquals("k1 two two", in.readLine()); + + s.close(); + } +} diff --git a/src/test/java/ru/hh/school/stdlib/SimpleGetTest.java b/src/test/java/ru/hh/school/stdlib/SimpleGetTest.java index 0fe1b49..cd9514f 100644 --- a/src/test/java/ru/hh/school/stdlib/SimpleGetTest.java +++ b/src/test/java/ru/hh/school/stdlib/SimpleGetTest.java @@ -15,7 +15,7 @@ public void simpleGet() throws IOException { Socket s = connect(); Writer out = new PrintWriter(s.getOutputStream()); - out.append("GET k1\n").flush(); + out.append("GET k3\n").flush(); BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream())); Assert.assertEquals("VALUE", in.readLine()); From fca2a70fd213011c2ccd4f88f6801a3e9f88eddf Mon Sep 17 00:00:00 2001 From: Oleg Lontsov Date: Fri, 13 Jan 2012 16:24:46 +0400 Subject: [PATCH 2/3] Modifications. Fix concurrency issues. --- .../ru/hh/school/stdlib/ClientHandler.java | 58 ++++++++++--------- .../java/ru/hh/school/stdlib/Launcher.java | 44 +++++++------- src/main/java/ru/hh/school/stdlib/Server.java | 57 ++++++++++-------- .../ru/hh/school/stdlib/Substitutor3000.java | 52 +++++++---------- .../hh/school/stdlib/BaseFunctionalTest.java | 52 ++++++++--------- .../java/ru/hh/school/stdlib/GetPutTest.java | 2 +- .../ru/hh/school/stdlib/RecursionTest.java | 12 ++-- .../ru/hh/school/stdlib/RecursiveGet.java | 9 +-- .../ru/hh/school/stdlib/SimpleGetTest.java | 33 +++++------ .../hh/school/stdlib/Substitutor3000Test.java | 32 +++++----- 10 files changed, 174 insertions(+), 177 deletions(-) diff --git a/src/main/java/ru/hh/school/stdlib/ClientHandler.java b/src/main/java/ru/hh/school/stdlib/ClientHandler.java index 240795c..411157f 100644 --- a/src/main/java/ru/hh/school/stdlib/ClientHandler.java +++ b/src/main/java/ru/hh/school/stdlib/ClientHandler.java @@ -4,56 +4,62 @@ import java.io.PrintWriter; import java.net.Socket; import java.util.Scanner; +import java.util.concurrent.TimeUnit; -public class ClientHandler implements Runnable{ +public class ClientHandler implements Runnable { private Socket incoming; private final Substitutor3000 sbst; + private final Server server; - public ClientHandler(Socket i, Substitutor3000 sb) { + public ClientHandler(Socket i, Server srv, Substitutor3000 sb) { incoming = i; + server = srv; sbst = sb; } @Override public void run() { - try{ + try { try { Scanner in = new Scanner(incoming.getInputStream()); PrintWriter out = new PrintWriter(incoming.getOutputStream()); String line = in.nextLine().trim(); - String[] req = line.split(" ", 3); + String[] req = line.split(" ", 3); int len = req.length; if (req[0].equals("GET")) { - Thread.sleep(sbst.getSleepTime()); - if(len>=2){ - out.println("VALUE"); - out.println(sbst.get(req[1]));} - else out.println("GET syntax: GET key"); - } - else if ((req[0].equals("SET"))&&(req[1].equals("SLEEP"))) { - if(len==3) synchronized (sbst){sbst.setSleepTime(Long.valueOf(req[2]));} - else out.println("SET syntax: SET SLEEP sleeptime"); - } - else if (req[0].equals("PUT")){ - Thread.sleep(sbst.getSleepTime()); - if(len==3){ + TimeUnit.MILLISECONDS.sleep(server.getSleepTime()); + if (len >= 2) { + try { + String temp; + temp = sbst.get(req[1], null); + out.println("VALUE"); + out.println(temp); + } catch (IOException e) { + out.println("Error: " + e.getMessage()); + } + } else out.println("GET syntax: GET key"); + } else if ((req[0].equals("SET")) && (req[1].equals("SLEEP"))) { + if (len == 3) { + server.setSleepTime(Long.valueOf(req[2])); + } else out.println("SET syntax: SET SLEEP sleeptime"); + } else if (req[0].equals("PUT")) { + TimeUnit.MILLISECONDS.sleep(server.getSleepTime()); + if (len == 3) { sbst.put(req[1], req[2]); out.println("OK"); - } - else out.println("PUT syntax: PUT key value"); - } - else out.println("Unsupported request! We accept GET, PUT or SET SLEEP here!"); + } else out.println("PUT syntax: PUT key value"); + } else out.println("Unsupported request! We accept GET, PUT or SET SLEEP here!"); out.flush(); - } catch (InterruptedException e) { + } catch (InterruptedException e) { e.printStackTrace(); - } finally{ + } finally { incoming.close(); } } catch (IOException e) { - e.printStackTrace(); - } - + e.printStackTrace(); + } + } } diff --git a/src/main/java/ru/hh/school/stdlib/Launcher.java b/src/main/java/ru/hh/school/stdlib/Launcher.java index 5ec5f98..92639b5 100644 --- a/src/main/java/ru/hh/school/stdlib/Launcher.java +++ b/src/main/java/ru/hh/school/stdlib/Launcher.java @@ -4,27 +4,27 @@ import java.net.InetSocketAddress; public class Launcher { - public static void main(String[] args) throws IOException { - String host; - int port; - try { - if (args.length == 0) { - host = "127.0.0.1"; - port = 9129; - } else if (args.length == 2) { - host = args[0]; - port = Integer.parseInt(args[1]); - } else { - throw new IllegalArgumentException(); - } - } catch (Exception e) { - System.err.printf("Usage: %s [host port]%n", args[0]); - for (String s: args) System.out.println(s); - e.printStackTrace(); - System.exit(1); - return; // попробуйте закомментировать этот return + public static void main(String[] args) throws IOException { + String host; + int port; + try { + if (args.length == 0) { + host = "127.0.0.1"; + port = 9129; + } else if (args.length == 2) { + host = args[0]; + port = Integer.parseInt(args[1]); + } else { + throw new IllegalArgumentException(); + } + } catch (Exception e) { + System.err.printf("Usage: %s [host port]%n", args[0]); + for (String s : args) System.out.println(s); + e.printStackTrace(); + System.exit(1); + return; // попробуйте закомментировать этот return + } + InetSocketAddress addr = InetSocketAddress.createUnresolved(host, port); + new Server(addr).run(); } - InetSocketAddress addr = InetSocketAddress.createUnresolved(host, port); - new Server(addr).run(); - } } diff --git a/src/main/java/ru/hh/school/stdlib/Server.java b/src/main/java/ru/hh/school/stdlib/Server.java index 6e4abaf..aaea695 100644 --- a/src/main/java/ru/hh/school/stdlib/Server.java +++ b/src/main/java/ru/hh/school/stdlib/Server.java @@ -4,33 +4,44 @@ import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; public class Server { - private ServerSocket s; - private Substitutor3000 sbst; - public Server(InetSocketAddress addr){ - try{ - s = new ServerSocket(addr.getPort()); - sbst = new Substitutor3000(); + private ServerSocket s; + private Substitutor3000 sbst; + private Long sleepTime; + + public Server(InetSocketAddress addr) { + try { + s = new ServerSocket(addr.getPort()); + sbst = new Substitutor3000(); + sleepTime = 0L; + } catch (IOException e) { + System.err.println("There's an I/O problem: "); + e.printStackTrace(); + System.exit(1); + } + } + + public void run() throws IOException { + System.out.printf("Server started on port %d%n", this.getPort()); + ExecutorService exec = Executors.newCachedThreadPool(); + while (true) { + Socket incoming = s.accept(); + exec.execute(new ClientHandler(incoming, this, sbst)); + } } - catch(IOException e){ - System.err.println("There's an I/O problem: "); - e.printStackTrace(); - System.exit(1); + + public int getPort() { + return s.getLocalPort(); } - } - public void run() throws IOException { - System.out.printf("Server started on port %d%n", this.getPort()); - while(true){ - Socket incoming = s.accept(); - Runnable r = new ClientHandler(incoming, sbst); - Thread t = new Thread(r); - t.start(); - } - } + public synchronized Long getSleepTime() { + return sleepTime; + } - public int getPort() { - return s.getLocalPort(); - } + public synchronized void setSleepTime(Long sleepTime) { + this.sleepTime = sleepTime; + } } diff --git a/src/main/java/ru/hh/school/stdlib/Substitutor3000.java b/src/main/java/ru/hh/school/stdlib/Substitutor3000.java index dce8394..4b087fb 100644 --- a/src/main/java/ru/hh/school/stdlib/Substitutor3000.java +++ b/src/main/java/ru/hh/school/stdlib/Substitutor3000.java @@ -1,5 +1,6 @@ package ru.hh.school.stdlib; +import java.io.IOException; import java.util.HashMap; import java.util.HashSet; import java.util.regex.Matcher; @@ -7,44 +8,33 @@ public class Substitutor3000 { - private long sleepTime; private HashMap storage; - private HashSet inProgress = new HashSet(); - private final String recursionPanicString = "Panic!!! Infinite recursion!!!"; public Substitutor3000() { storage = new HashMap(); } public synchronized void put(String key, String value) { - storage.put(key, value); - } - - public String get(String key) { - if (inProgress.contains(key)) { - inProgress.clear(); - return recursionPanicString; - } - String out = storage.get(key); - if(out==null) return ""; - inProgress.add(key); - Pattern pattern = Pattern.compile("\\p{Sc}\\{(\\S+)\\}"); - Matcher matcher = pattern.matcher(out); - while (matcher.find()){ - String part = get(matcher.group(1)); - if(part==null){ - part=""; - } - else if (part.equals(recursionPanicString)) return part; - out = out.replace(matcher.group(0),part); - } - inProgress.remove(key); - return out; - } - public long getSleepTime() { - return sleepTime; + storage.put(key, value); } - public void setSleepTime(long sleepTime) { - this.sleepTime = sleepTime; + + public synchronized String get(String key, HashSet inProgress) throws IOException { + if (inProgress == null) + inProgress = new HashSet(); + else if (inProgress.contains(key)) + throw new IOException("Infinite recursion."); + String out = storage.get(key); + if (out == null) return ""; + inProgress.add(key); + Pattern pattern = Pattern.compile("\\p{Sc}\\{(\\S+)\\}"); + Matcher matcher = pattern.matcher(out); + while (matcher.find()) { + String part = get(matcher.group(1), inProgress); + if (part == null) + part = ""; + out = out.replace(matcher.group(0), part); + } + inProgress.remove(key); + return out; } } diff --git a/src/test/java/ru/hh/school/stdlib/BaseFunctionalTest.java b/src/test/java/ru/hh/school/stdlib/BaseFunctionalTest.java index 5fb134c..5cd3493 100644 --- a/src/test/java/ru/hh/school/stdlib/BaseFunctionalTest.java +++ b/src/test/java/ru/hh/school/stdlib/BaseFunctionalTest.java @@ -5,36 +5,36 @@ import java.net.Socket; public class BaseFunctionalTest { - private static Server server; + private static Server server; - protected BaseFunctionalTest() { - synchronized (BaseFunctionalTest.class) { - try { - if (server == null) { - server = new Server(new InetSocketAddress("127.0.0.1", 0)); - new Thread(new Runnable() { - public void run() { - try { - server.run(); - } catch (IOException e) { + protected BaseFunctionalTest() { + synchronized (BaseFunctionalTest.class) { + try { + if (server == null) { + server = new Server(new InetSocketAddress("127.0.0.1", 0)); + new Thread(new Runnable() { + public void run() { + try { + server.run(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + }).start(); + Thread.sleep(100); + System.out.printf("Server started on port %d%n", server.getPort()); + } + } catch (Exception e) { throw new RuntimeException(e); - } } - }).start(); - Thread.sleep(100); - System.out.printf("Server started on port %d%n", server.getPort()); } - } catch (Exception e) { - throw new RuntimeException(e); - } } - } - - protected Socket connect() { - try { - return new Socket("127.0.0.1", server.getPort()); - } catch (IOException e) { - throw new RuntimeException(e); + + protected Socket connect() { + try { + return new Socket("127.0.0.1", server.getPort()); + } catch (IOException e) { + throw new RuntimeException(e); + } } - } } diff --git a/src/test/java/ru/hh/school/stdlib/GetPutTest.java b/src/test/java/ru/hh/school/stdlib/GetPutTest.java index e94495d..12eb752 100644 --- a/src/test/java/ru/hh/school/stdlib/GetPutTest.java +++ b/src/test/java/ru/hh/school/stdlib/GetPutTest.java @@ -7,7 +7,7 @@ import java.net.Socket; -public class GetPutTest extends BaseFunctionalTest{ +public class GetPutTest extends BaseFunctionalTest { @Test public void getPut() throws IOException { Socket s = connect(); diff --git a/src/test/java/ru/hh/school/stdlib/RecursionTest.java b/src/test/java/ru/hh/school/stdlib/RecursionTest.java index 930ae51..43ec6c6 100644 --- a/src/test/java/ru/hh/school/stdlib/RecursionTest.java +++ b/src/test/java/ru/hh/school/stdlib/RecursionTest.java @@ -1,14 +1,11 @@ package ru.hh.school.stdlib; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.PrintWriter; -import java.io.Writer; -import java.net.Socket; import org.junit.Assert; import org.junit.Test; +import java.io.*; +import java.net.Socket; + public class RecursionTest extends BaseFunctionalTest { //This one tests protection from infinite recursion @Test @@ -35,8 +32,7 @@ public void recursivePut() throws IOException { out = new PrintWriter(s.getOutputStream()); in = new BufferedReader(new InputStreamReader(s.getInputStream())); out.append("GET keys3\n").flush(); - Assert.assertEquals("VALUE", in.readLine()); - Assert.assertEquals("Panic!!! Infinite recursion!!!", in.readLine()); + Assert.assertEquals("Error: Infinite recursion.", in.readLine()); s.close(); } diff --git a/src/test/java/ru/hh/school/stdlib/RecursiveGet.java b/src/test/java/ru/hh/school/stdlib/RecursiveGet.java index 4927a4f..61d8c76 100644 --- a/src/test/java/ru/hh/school/stdlib/RecursiveGet.java +++ b/src/test/java/ru/hh/school/stdlib/RecursiveGet.java @@ -1,14 +1,11 @@ package ru.hh.school.stdlib; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.PrintWriter; -import java.io.Writer; -import java.net.Socket; import org.junit.Assert; import org.junit.Test; +import java.io.*; +import java.net.Socket; + public class RecursiveGet extends BaseFunctionalTest { //This is not a test for infinite recursion protection. @Test diff --git a/src/test/java/ru/hh/school/stdlib/SimpleGetTest.java b/src/test/java/ru/hh/school/stdlib/SimpleGetTest.java index cd9514f..72fc795 100644 --- a/src/test/java/ru/hh/school/stdlib/SimpleGetTest.java +++ b/src/test/java/ru/hh/school/stdlib/SimpleGetTest.java @@ -1,26 +1,23 @@ package ru.hh.school.stdlib; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.PrintWriter; -import java.io.Writer; -import java.net.Socket; import org.junit.Assert; import org.junit.Test; +import java.io.*; +import java.net.Socket; + public class SimpleGetTest extends BaseFunctionalTest { - @Test - public void simpleGet() throws IOException { - Socket s = connect(); + @Test + public void simpleGet() throws IOException { + Socket s = connect(); + + Writer out = new PrintWriter(s.getOutputStream()); + out.append("GET k3\n").flush(); + BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream())); + + Assert.assertEquals("VALUE", in.readLine()); + Assert.assertEquals("", in.readLine()); - Writer out = new PrintWriter(s.getOutputStream()); - out.append("GET k3\n").flush(); - BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream())); - - Assert.assertEquals("VALUE", in.readLine()); - Assert.assertEquals("", in.readLine()); - - s.close(); - } + s.close(); + } } diff --git a/src/test/java/ru/hh/school/stdlib/Substitutor3000Test.java b/src/test/java/ru/hh/school/stdlib/Substitutor3000Test.java index 3d63300..48e7f17 100644 --- a/src/test/java/ru/hh/school/stdlib/Substitutor3000Test.java +++ b/src/test/java/ru/hh/school/stdlib/Substitutor3000Test.java @@ -4,21 +4,21 @@ import org.junit.Test; public class Substitutor3000Test { - @Test - public void replacement() { - Substitutor3000 sbst = new Substitutor3000(); - sbst.put("k1", "one"); - sbst.put("k2", "two"); - sbst.put("keys", "1: ${k1}, 2: ${k2}"); - - Assert.assertEquals("1: one, 2: two", sbst.get("keys")); - } + @Test + public void replacement() throws Exception { + Substitutor3000 sbst = new Substitutor3000(); + sbst.put("k1", "one"); + sbst.put("k2", "two"); + sbst.put("keys", "1: ${k1}, 2: ${k2}"); - @Test - public void emptyReplacement() { - Substitutor3000 sbst = new Substitutor3000(); - sbst.put("k", "bla-${inexistent}-bla"); - - Assert.assertEquals("bla--bla", sbst.get("k")); - } + Assert.assertEquals("1: one, 2: two", sbst.get("keys", null)); + } + + @Test + public void emptyReplacement() throws Exception { + Substitutor3000 sbst = new Substitutor3000(); + sbst.put("k", "bla-${inexistent}-bla"); + + Assert.assertEquals("bla--bla", sbst.get("k", null)); + } } From 5e5ed0d5de40ee631607e9bc301e0989d85ce2cc Mon Sep 17 00:00:00 2001 From: Oleg Lontsov Date: Sun, 29 Jan 2012 19:59:27 +0400 Subject: [PATCH 3/3] Added InfiniteRecursionException. Unified ERROR messages. --- pom.xml | 83 ++++++++++--------- .../ru/hh/school/stdlib/ClientHandler.java | 12 +-- .../stdlib/InfiniteRecursionException.java | 7 ++ src/main/java/ru/hh/school/stdlib/Server.java | 4 +- .../ru/hh/school/stdlib/Substitutor3000.java | 5 +- 5 files changed, 59 insertions(+), 52 deletions(-) create mode 100644 src/main/java/ru/hh/school/stdlib/InfiniteRecursionException.java diff --git a/pom.xml b/pom.xml index ac574cc..ba0d124 100644 --- a/pom.xml +++ b/pom.xml @@ -1,46 +1,47 @@ - ru.hh.school - 4.0.0 - java-stdlib - jar - Homework exercise for 'Java Standard Library' lecture - 1.0-SNAPSHOT + ru.hh.school + 4.0.0 + java-stdlib + jar + Homework exercise for 'Java Standard Library' lecture + 1.0-SNAPSHOT - - - - org.apache.maven.plugins - maven-shade-plugin - 1.4 - - - package - - shade - - - ${project.artifactId} - - - - ru.hh.school.stdlib.Launcher - - - - - - - - - + + + + org.apache.maven.plugins + maven-shade-plugin + 1.4 + + + package + + shade + + + ${project.artifactId} + + + + ru.hh.school.stdlib.Launcher + + + + + + + + + - - - junit - junit - 4.7 - test - - + + + junit + junit + 4.7 + test + + diff --git a/src/main/java/ru/hh/school/stdlib/ClientHandler.java b/src/main/java/ru/hh/school/stdlib/ClientHandler.java index 411157f..4438390 100644 --- a/src/main/java/ru/hh/school/stdlib/ClientHandler.java +++ b/src/main/java/ru/hh/school/stdlib/ClientHandler.java @@ -35,21 +35,21 @@ public void run() { temp = sbst.get(req[1], null); out.println("VALUE"); out.println(temp); - } catch (IOException e) { - out.println("Error: " + e.getMessage()); + } catch (InfiniteRecursionException e) { + out.println("ERROR " + e.getMessage()); } - } else out.println("GET syntax: GET key"); + } else out.println("ERROR GET syntax: GET key"); } else if ((req[0].equals("SET")) && (req[1].equals("SLEEP"))) { if (len == 3) { server.setSleepTime(Long.valueOf(req[2])); - } else out.println("SET syntax: SET SLEEP sleeptime"); + } else out.println("ERROR SET syntax: SET SLEEP sleeptime"); } else if (req[0].equals("PUT")) { TimeUnit.MILLISECONDS.sleep(server.getSleepTime()); if (len == 3) { sbst.put(req[1], req[2]); out.println("OK"); - } else out.println("PUT syntax: PUT key value"); - } else out.println("Unsupported request! We accept GET, PUT or SET SLEEP here!"); + } else out.println("ERROR PUT syntax: PUT key value"); + } else out.println("ERROR Unsupported request! We accept GET, PUT or SET SLEEP here!"); out.flush(); } catch (InterruptedException e) { e.printStackTrace(); diff --git a/src/main/java/ru/hh/school/stdlib/InfiniteRecursionException.java b/src/main/java/ru/hh/school/stdlib/InfiniteRecursionException.java new file mode 100644 index 0000000..1c7eddb --- /dev/null +++ b/src/main/java/ru/hh/school/stdlib/InfiniteRecursionException.java @@ -0,0 +1,7 @@ +package ru.hh.school.stdlib; + +public class InfiniteRecursionException extends Exception { + public InfiniteRecursionException(String s) { + super(s); + } +} diff --git a/src/main/java/ru/hh/school/stdlib/Server.java b/src/main/java/ru/hh/school/stdlib/Server.java index aaea695..a4ec112 100644 --- a/src/main/java/ru/hh/school/stdlib/Server.java +++ b/src/main/java/ru/hh/school/stdlib/Server.java @@ -17,8 +17,8 @@ public Server(InetSocketAddress addr) { s = new ServerSocket(addr.getPort()); sbst = new Substitutor3000(); sleepTime = 0L; - } catch (IOException e) { - System.err.println("There's an I/O problem: "); + } catch (Exception e) { + System.err.print("ERROR "); e.printStackTrace(); System.exit(1); } diff --git a/src/main/java/ru/hh/school/stdlib/Substitutor3000.java b/src/main/java/ru/hh/school/stdlib/Substitutor3000.java index 4b087fb..fa342fd 100644 --- a/src/main/java/ru/hh/school/stdlib/Substitutor3000.java +++ b/src/main/java/ru/hh/school/stdlib/Substitutor3000.java @@ -1,6 +1,5 @@ package ru.hh.school.stdlib; -import java.io.IOException; import java.util.HashMap; import java.util.HashSet; import java.util.regex.Matcher; @@ -18,11 +17,11 @@ public synchronized void put(String key, String value) { storage.put(key, value); } - public synchronized String get(String key, HashSet inProgress) throws IOException { + public synchronized String get(String key, HashSet inProgress) throws InfiniteRecursionException { if (inProgress == null) inProgress = new HashSet(); else if (inProgress.contains(key)) - throw new IOException("Infinite recursion."); + throw new InfiniteRecursionException("Infinite recursion."); String out = storage.get(key); if (out == null) return ""; inProgress.add(key);