From 8d15c2d0e41fdf1fd846c2b36c68456b96eea19f Mon Sep 17 00:00:00 2001 From: Yuriy Date: Wed, 21 Dec 2011 02:21:38 +0400 Subject: [PATCH 01/11] myServer v 1.0 --- .../java/ru/hh/school/stdlib/Launcher.java | 67 ++++++++------ src/main/java/ru/hh/school/stdlib/Server.java | 84 +++++++++++++---- .../ru/hh/school/stdlib/ServerThread.java | 76 ++++++++++++++++ .../ru/hh/school/stdlib/Substitutor3000.java | 55 ++++++++--- .../hh/school/stdlib/BaseFunctionalTest.java | 80 ++++++++-------- .../ru/hh/school/stdlib/SimpleGetTest.java | 91 +++++++++++++------ .../hh/school/stdlib/Substitutor3000Test.java | 57 +++++++----- 7 files changed, 362 insertions(+), 148 deletions(-) create mode 100644 src/main/java/ru/hh/school/stdlib/ServerThread.java diff --git a/src/main/java/ru/hh/school/stdlib/Launcher.java b/src/main/java/ru/hh/school/stdlib/Launcher.java index 1bee1a8..31ea6ba 100644 --- a/src/main/java/ru/hh/school/stdlib/Launcher.java +++ b/src/main/java/ru/hh/school/stdlib/Launcher.java @@ -1,29 +1,38 @@ -package ru.hh.school.stdlib; - -import java.io.IOException; -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 == 3) { - host = args[1]; - port = Integer.parseInt(args[2]); - } else { - throw new IllegalArgumentException(); - } - } catch (Exception e) { - System.err.printf("Usage: %s [host port]%n", args[0]); - System.exit(1); - return; // попробуйте закомментировать этот return - } - InetSocketAddress addr = InetSocketAddress.createUnresolved(host, port); - - new Server(addr).run(); - } -} +package ru.hh.school.stdlib; + +import java.io.IOException; +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 == 3) { + host = args[1]; + port = Integer.parseInt(args[2]); + } else { + throw new IllegalArgumentException(); + } + } catch (Exception e) { + System.err.printf("Usage: %s [host port]%n", args[0]); + System.exit(1); + return; + } + InetSocketAddress addr = InetSocketAddress.createUnresolved(host, port); + + Server server = new Server(addr); + new Thread(server).start(); + //Launching server for 20 minutes + try { + Thread.sleep(12000 * 1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println("Stopping Server"); + server.stop(); + } +} diff --git a/src/main/java/ru/hh/school/stdlib/Server.java b/src/main/java/ru/hh/school/stdlib/Server.java index 8284c32..394b70d 100644 --- a/src/main/java/ru/hh/school/stdlib/Server.java +++ b/src/main/java/ru/hh/school/stdlib/Server.java @@ -1,18 +1,66 @@ -package ru.hh.school.stdlib; - -import java.io.IOException; -import java.net.InetSocketAddress; - -public class Server { - public Server(InetSocketAddress addr) { - throw new UnsupportedOperationException(); - } - - public void run() throws IOException { - throw new UnsupportedOperationException(); - } - - public int getPort() { - throw new UnsupportedOperationException(); - } -} +package ru.hh.school.stdlib; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.ServerSocket; +import java.net.Socket; + +public class Server implements Runnable { + private int serverPort = 4444; + private ServerSocket serverSocket = null; + private boolean isStopped = false; + + public static Substitutor3000 substitutor; + + public Server(InetSocketAddress addr) { + this.serverPort = addr.getPort(); + substitutor = new Substitutor3000(); + } + + public void run() { + + openServerSocket(); + while(! isStopped()){ + Socket clientSocket = null; + try { + clientSocket = this.serverSocket.accept(); + } catch (IOException e) { + if(isStopped()) { + System.out.println("Server Stopped.") ; + return; + } + throw new RuntimeException( + "Error accepting client connection", e); + } + new Thread( + new ServerThread(clientSocket) + ).start(); + } + System.out.println("Server Stopped.") ; + } + + public int getPort() { + return serverPort; + } + + private synchronized boolean isStopped() { + return this.isStopped; + } + + public synchronized void stop(){ + this.isStopped = true; + try { + this.serverSocket.close(); + } catch (IOException e) { + throw new RuntimeException("Error closing server", e); + } + } + + private void openServerSocket() { + try { + this.serverSocket = new ServerSocket(this.serverPort); + } catch (IOException e) { + throw new RuntimeException("Cannot open port 8080", e); + } + } +} \ No newline at end of file diff --git a/src/main/java/ru/hh/school/stdlib/ServerThread.java b/src/main/java/ru/hh/school/stdlib/ServerThread.java new file mode 100644 index 0000000..f475876 --- /dev/null +++ b/src/main/java/ru/hh/school/stdlib/ServerThread.java @@ -0,0 +1,76 @@ +package ru.hh.school.stdlib; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.net.Socket; +import java.util.StringTokenizer; + +public class ServerThread implements Runnable{ + + protected Socket clientSocket = null; + private final static String WRONG_REQUEST ="Wrond request. Please try again."; + + public ServerThread(Socket clientSocket) { + this.clientSocket = clientSocket; + } + + public void run() { + try { + PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); + BufferedReader in = new BufferedReader(new InputStreamReader( + clientSocket.getInputStream())); + String inputLine, outputLine; + + while ((inputLine = in.readLine()) != null) { + outputLine = processInput(inputLine); + out.println(outputLine); + if (outputLine.equals("EXIT")) + break; + } + + out.close(); + in.close(); + clientSocket.close(); + } catch (IOException e) { + //report exception somewhere. + e.printStackTrace(); + } + } + + private String processInput(String inputLine) { + StringTokenizer tokenizer = new StringTokenizer(inputLine); + String command = tokenizer.nextToken(); + if (command.equals("GET")) { + + String key = tokenizer.nextToken(); + return "VALUE\n" + Server.substitutor.get(key); + } + else if (command.equals("PUT")) { + String key = tokenizer.nextToken(); + String value = ""; + while (tokenizer.hasMoreTokens()) { + value += tokenizer.nextToken(); + } + Server.substitutor.put(key, value); + return "OK\nconnection closed"; + } + else if (command.equals("SET")) { + if (tokenizer.nextToken().equals("SLEEP")) { + try { + Thread.sleep(Integer.parseInt(tokenizer.nextToken())); + } catch (InterruptedException e) { + return ""; + } + } + } + else if (command.equals("EXIT")) { + return "EXITING"; + } + else { + return WRONG_REQUEST; + } + return ""; + } +} \ No newline at end of file diff --git a/src/main/java/ru/hh/school/stdlib/Substitutor3000.java b/src/main/java/ru/hh/school/stdlib/Substitutor3000.java index 728598c..f73d0d2 100644 --- a/src/main/java/ru/hh/school/stdlib/Substitutor3000.java +++ b/src/main/java/ru/hh/school/stdlib/Substitutor3000.java @@ -1,11 +1,44 @@ -package ru.hh.school.stdlib; - -public class Substitutor3000 { - public void put(String key, String value) { - throw new UnsupportedOperationException(); - } - - public String get(String key) { - throw new UnsupportedOperationException(); - } -} +package ru.hh.school.stdlib; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class Substitutor3000 { + + private static Map map = Collections.synchronizedMap(new HashMap()); + + public void put(String key, String value) { + synchronized (this) { + map.put(key, value); + } + } + + public String get(String key) { + synchronized (this) { + String value = map.get(key); + if (value == null) + return ""; + String regex = "\\$\\{(\\w+)\\}"; + Pattern p = Pattern.compile(regex); + Matcher m = p.matcher(value); + + while (m.find()) { + value = value.replaceFirst(regex, get(m.group(1))); + m = p.matcher(value); + } + + //Adding whitespace after retrieved words + String regex2 = "\\w+"; + Pattern p2 = Pattern.compile(regex2); + Matcher m2 = p2.matcher(value); + if (m2.matches()) + value += " "; + + return value; + } + } + +} diff --git a/src/test/java/ru/hh/school/stdlib/BaseFunctionalTest.java b/src/test/java/ru/hh/school/stdlib/BaseFunctionalTest.java index 5fb134c..70a262c 100644 --- a/src/test/java/ru/hh/school/stdlib/BaseFunctionalTest.java +++ b/src/test/java/ru/hh/school/stdlib/BaseFunctionalTest.java @@ -1,40 +1,40 @@ -package ru.hh.school.stdlib; - -import java.io.IOException; -import java.net.InetSocketAddress; -import java.net.Socket; - -public class BaseFunctionalTest { - 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) { - 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); - } - } -} +package ru.hh.school.stdlib; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.Socket; + +public class BaseFunctionalTest { + private static Server server; + + protected BaseFunctionalTest() { + synchronized (BaseFunctionalTest.class) { + try { + if (server == null) { + server = new Server(new InetSocketAddress("127.0.0.1", 4444)); + 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); + } + } + } + + 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/SimpleGetTest.java b/src/test/java/ru/hh/school/stdlib/SimpleGetTest.java index 0fe1b49..60d662b 100644 --- a/src/test/java/ru/hh/school/stdlib/SimpleGetTest.java +++ b/src/test/java/ru/hh/school/stdlib/SimpleGetTest.java @@ -1,26 +1,65 @@ -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 SimpleGetTest extends BaseFunctionalTest { - @Test - public void simpleGet() throws IOException { - Socket s = connect(); - - Writer out = new PrintWriter(s.getOutputStream()); - out.append("GET k1\n").flush(); - BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream())); - - Assert.assertEquals("VALUE", in.readLine()); - Assert.assertEquals("", in.readLine()); - - s.close(); - } -} +package ru.hh.school.stdlib; + +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(); + + Writer out = new PrintWriter(s.getOutputStream()); + out.append("GET k1\n").flush(); + BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream())); + + Assert.assertEquals("VALUE", in.readLine()); + Assert.assertEquals("", in.readLine()); + + out.append("PUT mo monday\n").flush(); + + Assert.assertEquals("OK", in.readLine()); + Assert.assertEquals("connection closed", in.readLine()); + + out.append("GET mo\n").flush(); + + Assert.assertEquals("VALUE", in.readLine()); + Assert.assertEquals("monday ", in.readLine()); + + out.append("PUT tu tuesday\n").flush(); + Assert.assertEquals("OK", in.readLine()); + Assert.assertEquals("connection closed", in.readLine()); + + out.append("PUT wed wednesday\n").flush(); + Assert.assertEquals("OK", in.readLine()); + Assert.assertEquals("connection closed", in.readLine()); + + out.append("PUT days1 ${mo} ${tu} ${wed}\n").flush(); + Assert.assertEquals("OK", in.readLine()); + Assert.assertEquals("connection closed", in.readLine()); + + out.append("PUT th thursday\n").flush(); + Assert.assertEquals("OK", in.readLine()); + Assert.assertEquals("connection closed", in.readLine()); + + out.append("PUT fr friday\n").flush(); + Assert.assertEquals("OK", in.readLine()); + Assert.assertEquals("connection closed", in.readLine()); + + out.append("PUT days2 ${th} ${fr}\n").flush(); + Assert.assertEquals("OK", in.readLine()); + Assert.assertEquals("connection closed", in.readLine()); + + out.append("PUT workdays ${days1} ${days2}\n").flush(); + Assert.assertEquals("OK", in.readLine()); + Assert.assertEquals("connection closed", in.readLine()); + + out.append("GET workdays\n").flush(); + Assert.assertEquals("VALUE", in.readLine()); + Assert.assertEquals("monday tuesday wednesday thursday friday ", in.readLine()); + + 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..2a1e89c 100644 --- a/src/test/java/ru/hh/school/stdlib/Substitutor3000Test.java +++ b/src/test/java/ru/hh/school/stdlib/Substitutor3000Test.java @@ -1,24 +1,33 @@ -package ru.hh.school.stdlib; - -import org.junit.Assert; -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 emptyReplacement() { - Substitutor3000 sbst = new Substitutor3000(); - sbst.put("k", "bla-${inexistent}-bla"); - - Assert.assertEquals("bla--bla", sbst.get("k")); - } -} +package ru.hh.school.stdlib; + +import org.junit.Assert; +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")); + + sbst.put("a", "avril"); + sbst.put("keys2", "1: ${a}, 2: ${b}"); + Assert.assertEquals("1: avril, 2: ", sbst.get("keys2")); + + sbst.put("c3po", "human robot"); + sbst.put("r2d2", "wheel robot"); + sbst.put("keys3", "1: ${c3po}, 2: ${r2d2}"); + Assert.assertEquals("1: human robot, 2: wheel robot", sbst.get("keys3")); + } + + @Test + public void emptyReplacement() { + Substitutor3000 sbst = new Substitutor3000(); + sbst.put("k", "bla-${inexistent}-bla"); + + Assert.assertEquals("bla--bla", sbst.get("k")); + } +} From a80a58bb314b2d8d9d68bbc95b1cffe7ce44ad3a Mon Sep 17 00:00:00 2001 From: Yuriy Date: Wed, 21 Dec 2011 02:57:41 +0400 Subject: [PATCH 02/11] myServer v 1.0 --- .../ru/hh/school/stdlib/MultiConnection.java | 39 +++++++++++++++++++ .../ru/hh/school/stdlib/SimpleGetTest.java | 18 +++++++++ 2 files changed, 57 insertions(+) create mode 100644 src/test/java/ru/hh/school/stdlib/MultiConnection.java diff --git a/src/test/java/ru/hh/school/stdlib/MultiConnection.java b/src/test/java/ru/hh/school/stdlib/MultiConnection.java new file mode 100644 index 0000000..fee8580 --- /dev/null +++ b/src/test/java/ru/hh/school/stdlib/MultiConnection.java @@ -0,0 +1,39 @@ +package ru.hh.school.stdlib; + +import org.junit.Assert; +import org.junit.Test; + +import java.io.*; +import java.net.Socket; + +public class MultiConnection extends BaseFunctionalTest{ + + @Test + public void testMultiConnection() throws IOException{ + long timePeriod = 10000; + + Socket s1 = connect(); + Socket s2 = connect(); + + Writer out1 = new PrintWriter(s1.getOutputStream()); + BufferedReader in1 = new BufferedReader(new InputStreamReader(s1.getInputStream())); + Writer out2 = new PrintWriter(s2.getOutputStream()); + BufferedReader in2 = new BufferedReader(new InputStreamReader(s2.getInputStream())); + + out1.append("SET SLEEP " + timePeriod + "\n").flush(); + out2.append("SET SLEEP " + timePeriod + "\n").flush(); + long start = System.currentTimeMillis(); + out1.append("GET k1\n").flush(); + out2.append("GET k1\n").flush(); + Assert.assertEquals("", in1.readLine()); + Assert.assertEquals("VALUE", in1.readLine()); + Assert.assertEquals("", in1.readLine()); + Assert.assertEquals("", in2.readLine()); + Assert.assertEquals("VALUE", in2.readLine()); + Assert.assertEquals("", in2.readLine()); + long end = System.currentTimeMillis(); + + Assert.assertTrue((end - start) < (timePeriod * 2)); + System.out.println(end - start); + } +} diff --git a/src/test/java/ru/hh/school/stdlib/SimpleGetTest.java b/src/test/java/ru/hh/school/stdlib/SimpleGetTest.java index 60d662b..aec3dbf 100644 --- a/src/test/java/ru/hh/school/stdlib/SimpleGetTest.java +++ b/src/test/java/ru/hh/school/stdlib/SimpleGetTest.java @@ -62,4 +62,22 @@ public void simpleGet() throws IOException { s.close(); } + + @Test + public void testSleep() throws IOException { + long timePeriod = 10000; + Socket t = connect(); + Writer out = new PrintWriter(t.getOutputStream()); + BufferedReader in = new BufferedReader(new InputStreamReader(t.getInputStream())); + + out.append("SET SLEEP " + timePeriod + "\n").flush(); + long start = System.currentTimeMillis(); + out.append("GET k1\n").flush(); + Assert.assertEquals("", in.readLine()); + Assert.assertEquals("VALUE", in.readLine()); + Assert.assertEquals("", in.readLine()); + long end = System.currentTimeMillis(); + Assert.assertTrue(timePeriod < (end - start)); + Assert.assertTrue((end - start) < (timePeriod + 50)); + } } From 1389dd1f43efa015f9010c2ffeb451a82e65f215 Mon Sep 17 00:00:00 2001 From: Yuriy Date: Wed, 21 Dec 2011 14:54:53 +0400 Subject: [PATCH 03/11] myServer v 1.0 --- .../ru/hh/school/stdlib/ServerThread.java | 4 +-- .../ru/hh/school/stdlib/Substitutor3000.java | 26 ++++++++++++++++--- .../ru/hh/school/stdlib/SimpleGetTest.java | 6 ++--- .../hh/school/stdlib/Substitutor3000Test.java | 9 +++++-- 4 files changed, 34 insertions(+), 11 deletions(-) diff --git a/src/main/java/ru/hh/school/stdlib/ServerThread.java b/src/main/java/ru/hh/school/stdlib/ServerThread.java index f475876..352061d 100644 --- a/src/main/java/ru/hh/school/stdlib/ServerThread.java +++ b/src/main/java/ru/hh/school/stdlib/ServerThread.java @@ -34,7 +34,6 @@ public void run() { in.close(); clientSocket.close(); } catch (IOException e) { - //report exception somewhere. e.printStackTrace(); } } @@ -53,7 +52,8 @@ else if (command.equals("PUT")) { while (tokenizer.hasMoreTokens()) { value += tokenizer.nextToken(); } - Server.substitutor.put(key, value); + if (Server.substitutor.put(key, value).equals("Error. Cycle reference.")) + return "Error. Cycle reference."; return "OK\nconnection closed"; } else if (command.equals("SET")) { diff --git a/src/main/java/ru/hh/school/stdlib/Substitutor3000.java b/src/main/java/ru/hh/school/stdlib/Substitutor3000.java index f73d0d2..46b0a7c 100644 --- a/src/main/java/ru/hh/school/stdlib/Substitutor3000.java +++ b/src/main/java/ru/hh/school/stdlib/Substitutor3000.java @@ -1,18 +1,32 @@ package ru.hh.school.stdlib; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; +import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Substitutor3000 { private static Map map = Collections.synchronizedMap(new HashMap()); + private Set keysSet = new HashSet(); + private String ErrorCycRef = "Error. Cycle reference."; - public void put(String key, String value) { + public String put(String key, String value) { synchronized (this) { + + String regex = "\\$\\{(\\w+)\\}"; + Pattern p = Pattern.compile(regex); + Matcher m = p.matcher(value); + + keysSet.add(key); + String chvalue; + while (m.find()) { + chvalue = m.group(1); + if (get(chvalue).equals(ErrorCycRef)) + return ErrorCycRef; + } map.put(key, value); + keysSet.remove(key); + return ""; } } @@ -26,6 +40,10 @@ public String get(String key) { Matcher m = p.matcher(value); while (m.find()) { + //Cheching whether keys don't reference each other + if (keysSet.contains(m.group(1))) { + return ErrorCycRef; + } value = value.replaceFirst(regex, get(m.group(1))); m = p.matcher(value); } diff --git a/src/test/java/ru/hh/school/stdlib/SimpleGetTest.java b/src/test/java/ru/hh/school/stdlib/SimpleGetTest.java index aec3dbf..9db7885 100644 --- a/src/test/java/ru/hh/school/stdlib/SimpleGetTest.java +++ b/src/test/java/ru/hh/school/stdlib/SimpleGetTest.java @@ -65,7 +65,7 @@ public void simpleGet() throws IOException { @Test public void testSleep() throws IOException { - long timePeriod = 10000; + long timePeriod = 1000; Socket t = connect(); Writer out = new PrintWriter(t.getOutputStream()); BufferedReader in = new BufferedReader(new InputStreamReader(t.getInputStream())); @@ -77,7 +77,7 @@ public void testSleep() throws IOException { Assert.assertEquals("VALUE", in.readLine()); Assert.assertEquals("", in.readLine()); long end = System.currentTimeMillis(); - Assert.assertTrue(timePeriod < (end - start)); - Assert.assertTrue((end - start) < (timePeriod + 50)); + Assert.assertTrue(timePeriod - 100 < (end - start)); + Assert.assertTrue((end - start) < (timePeriod + 100)); } } diff --git a/src/test/java/ru/hh/school/stdlib/Substitutor3000Test.java b/src/test/java/ru/hh/school/stdlib/Substitutor3000Test.java index 2a1e89c..f316921 100644 --- a/src/test/java/ru/hh/school/stdlib/Substitutor3000Test.java +++ b/src/test/java/ru/hh/school/stdlib/Substitutor3000Test.java @@ -11,16 +11,21 @@ public void replacement() { sbst.put("k2", "two"); sbst.put("keys", "1: ${k1}, 2: ${k2}"); - Assert.assertEquals("1: one, 2: two", sbst.get("keys")); + Assert.assertEquals("1: one , 2: two ", sbst.get("keys")); sbst.put("a", "avril"); sbst.put("keys2", "1: ${a}, 2: ${b}"); - Assert.assertEquals("1: avril, 2: ", sbst.get("keys2")); + Assert.assertEquals("1: avril , 2: ", sbst.get("keys2")); sbst.put("c3po", "human robot"); sbst.put("r2d2", "wheel robot"); sbst.put("keys3", "1: ${c3po}, 2: ${r2d2}"); Assert.assertEquals("1: human robot, 2: wheel robot", sbst.get("keys3")); + + //Checking how cycle references are handled + sbst.put("r1","${r2}"); + sbst.put("r2","${r3}"); + Assert.assertTrue(("Error. Cycle reference.".equals(sbst.put("r3","${r1}")))); } @Test From b34408da687ddd7bbe9084ac84164f58d704bf44 Mon Sep 17 00:00:00 2001 From: Yuriy Khamzyaev Date: Fri, 13 Jan 2012 19:58:24 +0400 Subject: [PATCH 04/11] removed usage of statics --- .../java/ru/hh/school/stdlib/Launcher.java | 68 ++++---- src/main/java/ru/hh/school/stdlib/Server.java | 106 +++++------- .../ru/hh/school/stdlib/ServerThread.java | 152 +++++++++--------- .../ru/hh/school/stdlib/Substitutor3000.java | 122 +++++++------- 4 files changed, 208 insertions(+), 240 deletions(-) diff --git a/src/main/java/ru/hh/school/stdlib/Launcher.java b/src/main/java/ru/hh/school/stdlib/Launcher.java index 31ea6ba..cca80cf 100644 --- a/src/main/java/ru/hh/school/stdlib/Launcher.java +++ b/src/main/java/ru/hh/school/stdlib/Launcher.java @@ -1,38 +1,30 @@ -package ru.hh.school.stdlib; - -import java.io.IOException; -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 == 3) { - host = args[1]; - port = Integer.parseInt(args[2]); - } else { - throw new IllegalArgumentException(); - } - } catch (Exception e) { - System.err.printf("Usage: %s [host port]%n", args[0]); - System.exit(1); - return; - } - InetSocketAddress addr = InetSocketAddress.createUnresolved(host, port); - - Server server = new Server(addr); - new Thread(server).start(); - //Launching server for 20 minutes - try { - Thread.sleep(12000 * 1000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - System.out.println("Stopping Server"); - server.stop(); - } -} +package ru.hh.school.stdlib; + +import java.io.IOException; +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 == 3) { + host = args[1]; + port = Integer.parseInt(args[2]); + } else { + throw new IllegalArgumentException(); + } + } catch (Exception e) { + System.err.printf("Usage: %s [host port]%n", args[0]); + System.exit(1); + return; + } + InetSocketAddress addr = InetSocketAddress.createUnresolved(host, port); + + Server server = new Server(addr); + new Thread(server).start(); + } +} diff --git a/src/main/java/ru/hh/school/stdlib/Server.java b/src/main/java/ru/hh/school/stdlib/Server.java index 394b70d..a8c45b3 100644 --- a/src/main/java/ru/hh/school/stdlib/Server.java +++ b/src/main/java/ru/hh/school/stdlib/Server.java @@ -1,66 +1,42 @@ -package ru.hh.school.stdlib; - -import java.io.IOException; -import java.net.InetSocketAddress; -import java.net.ServerSocket; -import java.net.Socket; - -public class Server implements Runnable { - private int serverPort = 4444; - private ServerSocket serverSocket = null; - private boolean isStopped = false; - - public static Substitutor3000 substitutor; - - public Server(InetSocketAddress addr) { - this.serverPort = addr.getPort(); - substitutor = new Substitutor3000(); - } - - public void run() { - - openServerSocket(); - while(! isStopped()){ - Socket clientSocket = null; - try { - clientSocket = this.serverSocket.accept(); - } catch (IOException e) { - if(isStopped()) { - System.out.println("Server Stopped.") ; - return; - } - throw new RuntimeException( - "Error accepting client connection", e); - } - new Thread( - new ServerThread(clientSocket) - ).start(); - } - System.out.println("Server Stopped.") ; - } - - public int getPort() { - return serverPort; - } - - private synchronized boolean isStopped() { - return this.isStopped; - } - - public synchronized void stop(){ - this.isStopped = true; - try { - this.serverSocket.close(); - } catch (IOException e) { - throw new RuntimeException("Error closing server", e); - } - } - - private void openServerSocket() { - try { - this.serverSocket = new ServerSocket(this.serverPort); - } catch (IOException e) { - throw new RuntimeException("Cannot open port 8080", e); - } - } +package ru.hh.school.stdlib; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.ServerSocket; +import java.net.Socket; + +public class Server implements Runnable { + private int serverPort = 4444; + private ServerSocket serverSocket = null; + private Substitutor3000 substitutor; + + public Server(InetSocketAddress addr) { + this.serverPort = addr.getPort(); + substitutor = new Substitutor3000(); + } + + public void run() { + openServerSocket(); + while(true){ + Socket clientSocket; + try { + clientSocket = this.serverSocket.accept(); + } catch (IOException e) { + throw new RuntimeException("Error accepting client connection", e); + } + new Thread(new ServerThread(clientSocket, substitutor)).start(); + } + } + + public int getPort() { + return serverPort; + } + + private void openServerSocket() { + try { + this.serverSocket = new ServerSocket(this.serverPort); + } catch (IOException e) { + throw new RuntimeException("Cannot open port 8080", e); + } + } } \ No newline at end of file diff --git a/src/main/java/ru/hh/school/stdlib/ServerThread.java b/src/main/java/ru/hh/school/stdlib/ServerThread.java index 352061d..47e9df0 100644 --- a/src/main/java/ru/hh/school/stdlib/ServerThread.java +++ b/src/main/java/ru/hh/school/stdlib/ServerThread.java @@ -1,76 +1,78 @@ -package ru.hh.school.stdlib; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.PrintWriter; -import java.net.Socket; -import java.util.StringTokenizer; - -public class ServerThread implements Runnable{ - - protected Socket clientSocket = null; - private final static String WRONG_REQUEST ="Wrond request. Please try again."; - - public ServerThread(Socket clientSocket) { - this.clientSocket = clientSocket; - } - - public void run() { - try { - PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); - BufferedReader in = new BufferedReader(new InputStreamReader( - clientSocket.getInputStream())); - String inputLine, outputLine; - - while ((inputLine = in.readLine()) != null) { - outputLine = processInput(inputLine); - out.println(outputLine); - if (outputLine.equals("EXIT")) - break; - } - - out.close(); - in.close(); - clientSocket.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - private String processInput(String inputLine) { - StringTokenizer tokenizer = new StringTokenizer(inputLine); - String command = tokenizer.nextToken(); - if (command.equals("GET")) { - - String key = tokenizer.nextToken(); - return "VALUE\n" + Server.substitutor.get(key); - } - else if (command.equals("PUT")) { - String key = tokenizer.nextToken(); - String value = ""; - while (tokenizer.hasMoreTokens()) { - value += tokenizer.nextToken(); - } - if (Server.substitutor.put(key, value).equals("Error. Cycle reference.")) - return "Error. Cycle reference."; - return "OK\nconnection closed"; - } - else if (command.equals("SET")) { - if (tokenizer.nextToken().equals("SLEEP")) { - try { - Thread.sleep(Integer.parseInt(tokenizer.nextToken())); - } catch (InterruptedException e) { - return ""; - } - } - } - else if (command.equals("EXIT")) { - return "EXITING"; - } - else { - return WRONG_REQUEST; - } - return ""; - } +package ru.hh.school.stdlib; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.net.Socket; +import java.util.StringTokenizer; + +public class ServerThread implements Runnable{ + + protected Socket clientSocket = null; + private final static String WRONG_REQUEST ="Wrong request. Please try again."; + private Substitutor3000 substitutor; + + public ServerThread(Socket clientSocket, Substitutor3000 substitutor) { + this.clientSocket = clientSocket; + this.substitutor = substitutor; + } + + public void run() { + try { + PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); + BufferedReader in = new BufferedReader(new InputStreamReader( + clientSocket.getInputStream())); + String inputLine, outputLine; + + while ((inputLine = in.readLine()) != null) { + outputLine = processInput(inputLine); + out.println(outputLine); + if (outputLine.equals("EXIT")) + break; + } + + out.close(); + in.close(); + clientSocket.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private String processInput(String inputLine) { + StringTokenizer tokenizer = new StringTokenizer(inputLine); + String command = tokenizer.nextToken(); + if (command.equals("GET")) { + + String key = tokenizer.nextToken(); + return "VALUE\n" + substitutor.get(key); + } + else if (command.equals("PUT")) { + String key = tokenizer.nextToken(); + String value = ""; + while (tokenizer.hasMoreTokens()) { + value += tokenizer.nextToken(); + } + if (substitutor.put(key, value).equals("Error. Cycle reference.")) + return "Error. Cycle reference."; + return "OK\nconnection closed"; + } + else if (command.equals("SET")) { + if (tokenizer.nextToken().equals("SLEEP")) { + try { + Thread.sleep(Integer.parseInt(tokenizer.nextToken())); + } catch (InterruptedException e) { + return ""; + } + } + } + else if (command.equals("EXIT")) { + return "EXITING"; + } + else { + return WRONG_REQUEST; + } + return ""; + } } \ No newline at end of file diff --git a/src/main/java/ru/hh/school/stdlib/Substitutor3000.java b/src/main/java/ru/hh/school/stdlib/Substitutor3000.java index 46b0a7c..874b526 100644 --- a/src/main/java/ru/hh/school/stdlib/Substitutor3000.java +++ b/src/main/java/ru/hh/school/stdlib/Substitutor3000.java @@ -1,62 +1,60 @@ -package ru.hh.school.stdlib; - -import java.util.*; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class Substitutor3000 { - - private static Map map = Collections.synchronizedMap(new HashMap()); - private Set keysSet = new HashSet(); - private String ErrorCycRef = "Error. Cycle reference."; - - public String put(String key, String value) { - synchronized (this) { - - String regex = "\\$\\{(\\w+)\\}"; - Pattern p = Pattern.compile(regex); - Matcher m = p.matcher(value); - - keysSet.add(key); - String chvalue; - while (m.find()) { - chvalue = m.group(1); - if (get(chvalue).equals(ErrorCycRef)) - return ErrorCycRef; - } - map.put(key, value); - keysSet.remove(key); - return ""; - } - } - - public String get(String key) { - synchronized (this) { - String value = map.get(key); - if (value == null) - return ""; - String regex = "\\$\\{(\\w+)\\}"; - Pattern p = Pattern.compile(regex); - Matcher m = p.matcher(value); - - while (m.find()) { - //Cheching whether keys don't reference each other - if (keysSet.contains(m.group(1))) { - return ErrorCycRef; - } - value = value.replaceFirst(regex, get(m.group(1))); - m = p.matcher(value); - } - - //Adding whitespace after retrieved words - String regex2 = "\\w+"; - Pattern p2 = Pattern.compile(regex2); - Matcher m2 = p2.matcher(value); - if (m2.matches()) - value += " "; - - return value; - } - } - -} +package ru.hh.school.stdlib; + +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class Substitutor3000 { + + private Map map = Collections.synchronizedMap(new HashMap()); + private Set keysSet = new HashSet(); + private String ErrorCycRef = "Error. Cycle reference."; + private String regex = "\\$\\{(\\w+)\\}"; + + public String put(String key, String value) { + synchronized (this) { + Pattern p = Pattern.compile(regex); + Matcher m = p.matcher(value); + + keysSet.add(key); + String chvalue; + while (m.find()) { + chvalue = m.group(1); + if (get(chvalue).equals(ErrorCycRef)) + return ErrorCycRef; + } + map.put(key, value); + keysSet.remove(key); + return ""; + } + } + + public String get(String key) { + synchronized (this) { + String value = map.get(key); + if (value == null) + return ""; + Pattern p = Pattern.compile(regex); + Matcher m = p.matcher(value); + + while (m.find()) { + //Checking whether keys don't reference each other + if (keysSet.contains(m.group(1))) { + return ErrorCycRef; + } + value = value.replaceFirst(regex, get(m.group(1))); + m = p.matcher(value); + } + + //Adding whitespace after retrieved words + String regex2 = "\\w+"; + Pattern p2 = Pattern.compile(regex2); + Matcher m2 = p2.matcher(value); + if (m2.matches()) + value += " "; + + return value; + } + } + +} From e3355e753d3070d95a6b167ac6a24a489b1b886a Mon Sep 17 00:00:00 2001 From: Yuriy Khamzyaev Date: Sun, 15 Jan 2012 20:13:38 +0400 Subject: [PATCH 05/11] replaced new Thread() with Executors --- .../java/ru/hh/school/stdlib/Launcher.java | 38 +++++++++---------- src/main/java/ru/hh/school/stdlib/Server.java | 4 +- .../ru/hh/school/stdlib/ServerThread.java | 3 +- 3 files changed, 23 insertions(+), 22 deletions(-) diff --git a/src/main/java/ru/hh/school/stdlib/Launcher.java b/src/main/java/ru/hh/school/stdlib/Launcher.java index cca80cf..044723e 100644 --- a/src/main/java/ru/hh/school/stdlib/Launcher.java +++ b/src/main/java/ru/hh/school/stdlib/Launcher.java @@ -2,29 +2,29 @@ import java.io.IOException; import java.net.InetSocketAddress; +import java.util.concurrent.*; public class Launcher { - public static void main(String[] args) throws IOException { - String host; - int port; + 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 == 3) { - host = args[1]; - port = Integer.parseInt(args[2]); - } else { - throw new IllegalArgumentException(); - } + 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 { + throw new IllegalArgumentException(); + } } catch (Exception e) { - System.err.printf("Usage: %s [host port]%n", args[0]); - System.exit(1); - return; + System.err.printf("Usage: %s [host port]%n", args[0]); + System.exit(1); + return; } InetSocketAddress addr = InetSocketAddress.createUnresolved(host, port); - - Server server = new Server(addr); - new Thread(server).start(); - } + ExecutorService exec = Executors.newSingleThreadExecutor(); + exec.execute(new Server(addr)); + } } diff --git a/src/main/java/ru/hh/school/stdlib/Server.java b/src/main/java/ru/hh/school/stdlib/Server.java index a8c45b3..7882525 100644 --- a/src/main/java/ru/hh/school/stdlib/Server.java +++ b/src/main/java/ru/hh/school/stdlib/Server.java @@ -4,6 +4,7 @@ import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; +import java.util.concurrent.*; public class Server implements Runnable { private int serverPort = 4444; @@ -17,6 +18,7 @@ public Server(InetSocketAddress addr) { public void run() { openServerSocket(); + ExecutorService exec = Executors.newCachedThreadPool(); while(true){ Socket clientSocket; try { @@ -24,7 +26,7 @@ public void run() { } catch (IOException e) { throw new RuntimeException("Error accepting client connection", e); } - new Thread(new ServerThread(clientSocket, substitutor)).start(); + exec.execute(new ServerThread(clientSocket, substitutor)); } } diff --git a/src/main/java/ru/hh/school/stdlib/ServerThread.java b/src/main/java/ru/hh/school/stdlib/ServerThread.java index 47e9df0..eb321de 100644 --- a/src/main/java/ru/hh/school/stdlib/ServerThread.java +++ b/src/main/java/ru/hh/school/stdlib/ServerThread.java @@ -21,8 +21,7 @@ public ServerThread(Socket clientSocket, Substitutor3000 substitutor) { public void run() { try { PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); - BufferedReader in = new BufferedReader(new InputStreamReader( - clientSocket.getInputStream())); + BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); String inputLine, outputLine; while ((inputLine = in.readLine()) != null) { From 94c5783baab89f86451974388d2afcf2da853caf Mon Sep 17 00:00:00 2001 From: Yuriy Khamzyaev Date: Wed, 18 Jan 2012 14:45:55 +0400 Subject: [PATCH 06/11] Fixed the SET SLEEP command and removed check for recursive links in keys --- .../java/ru/hh/school/stdlib/Launcher.java | 29 +++---- src/main/java/ru/hh/school/stdlib/Server.java | 13 +++- .../ru/hh/school/stdlib/ServerThread.java | 42 ++++++---- .../ru/hh/school/stdlib/Substitutor3000.java | 30 +------ .../ru/hh/school/stdlib/MultiConnection.java | 78 +++++++++---------- .../hh/school/stdlib/Substitutor3000Test.java | 78 ++++++++++--------- 6 files changed, 135 insertions(+), 135 deletions(-) diff --git a/src/main/java/ru/hh/school/stdlib/Launcher.java b/src/main/java/ru/hh/school/stdlib/Launcher.java index 044723e..daff354 100644 --- a/src/main/java/ru/hh/school/stdlib/Launcher.java +++ b/src/main/java/ru/hh/school/stdlib/Launcher.java @@ -8,21 +8,22 @@ 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 == 3) { - host = args[1]; - port = Integer.parseInt(args[2]); - } else { - throw new IllegalArgumentException(); + try { + 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 { + throw new IllegalArgumentException(); + } + } catch (Exception e) { + System.err.printf("Usage: %s [host port]%n", args[0]); + System.exit(1); + return; } - } catch (Exception e) { - System.err.printf("Usage: %s [host port]%n", args[0]); - System.exit(1); - return; - } + InetSocketAddress addr = InetSocketAddress.createUnresolved(host, port); ExecutorService exec = Executors.newSingleThreadExecutor(); exec.execute(new Server(addr)); diff --git a/src/main/java/ru/hh/school/stdlib/Server.java b/src/main/java/ru/hh/school/stdlib/Server.java index 7882525..d133add 100644 --- a/src/main/java/ru/hh/school/stdlib/Server.java +++ b/src/main/java/ru/hh/school/stdlib/Server.java @@ -10,7 +10,8 @@ public class Server implements Runnable { private int serverPort = 4444; private ServerSocket serverSocket = null; private Substitutor3000 substitutor; - + private int sleepTime = 0; + public Server(InetSocketAddress addr) { this.serverPort = addr.getPort(); substitutor = new Substitutor3000(); @@ -26,7 +27,7 @@ public void run() { } catch (IOException e) { throw new RuntimeException("Error accepting client connection", e); } - exec.execute(new ServerThread(clientSocket, substitutor)); + exec.execute(new ServerThread(clientSocket, substitutor, this)); } } @@ -41,4 +42,12 @@ private void openServerSocket() { throw new RuntimeException("Cannot open port 8080", e); } } + + public int getSleepTime() { + return sleepTime; + } + + public void setSleepTime(int sleepTime) { + this.sleepTime = sleepTime; + } } \ No newline at end of file diff --git a/src/main/java/ru/hh/school/stdlib/ServerThread.java b/src/main/java/ru/hh/school/stdlib/ServerThread.java index eb321de..7629e6f 100644 --- a/src/main/java/ru/hh/school/stdlib/ServerThread.java +++ b/src/main/java/ru/hh/school/stdlib/ServerThread.java @@ -6,16 +6,20 @@ import java.io.PrintWriter; import java.net.Socket; import java.util.StringTokenizer; +import java.util.concurrent.TimeUnit; public class ServerThread implements Runnable{ - - protected Socket clientSocket = null; private final static String WRONG_REQUEST ="Wrong request. Please try again."; - private Substitutor3000 substitutor; + private final static String SUCCESS_REQUEST = "OK\nconnection closed"; - public ServerThread(Socket clientSocket, Substitutor3000 substitutor) { + private Socket clientSocket; + private Substitutor3000 substitutor; + private Server server; + + public ServerThread(Socket clientSocket, Substitutor3000 substitutor, Server server) { this.clientSocket = clientSocket; this.substitutor = substitutor; + this.server = server; } public void run() { @@ -43,35 +47,43 @@ private String processInput(String inputLine) { StringTokenizer tokenizer = new StringTokenizer(inputLine); String command = tokenizer.nextToken(); if (command.equals("GET")) { - + sleep(); String key = tokenizer.nextToken(); return "VALUE\n" + substitutor.get(key); } else if (command.equals("PUT")) { + sleep(); String key = tokenizer.nextToken(); String value = ""; while (tokenizer.hasMoreTokens()) { value += tokenizer.nextToken(); } - if (substitutor.put(key, value).equals("Error. Cycle reference.")) - return "Error. Cycle reference."; - return "OK\nconnection closed"; + substitutor.put(key, value); + return SUCCESS_REQUEST; } else if (command.equals("SET")) { if (tokenizer.nextToken().equals("SLEEP")) { - try { - Thread.sleep(Integer.parseInt(tokenizer.nextToken())); - } catch (InterruptedException e) { - return ""; - } + server.setSleepTime(Integer.parseInt(tokenizer.nextToken())); + return SUCCESS_REQUEST; } + else + return WRONG_REQUEST; } else if (command.equals("EXIT")) { - return "EXITING"; + return "EXIT"; } else { return WRONG_REQUEST; } - return ""; + } + + private void sleep() { + if (server.getSleepTime() != 0) { + try { + TimeUnit.MILLISECONDS.sleep(server.getSleepTime()); + } catch (InterruptedException e) { + System.out.println(e); + } + } } } \ No newline at end of file diff --git a/src/main/java/ru/hh/school/stdlib/Substitutor3000.java b/src/main/java/ru/hh/school/stdlib/Substitutor3000.java index 874b526..74e8c52 100644 --- a/src/main/java/ru/hh/school/stdlib/Substitutor3000.java +++ b/src/main/java/ru/hh/school/stdlib/Substitutor3000.java @@ -5,32 +5,17 @@ import java.util.regex.Pattern; public class Substitutor3000 { - private Map map = Collections.synchronizedMap(new HashMap()); - private Set keysSet = new HashSet(); - private String ErrorCycRef = "Error. Cycle reference."; - private String regex = "\\$\\{(\\w+)\\}"; - public String put(String key, String value) { + public void put(String key, String value) { synchronized (this) { - Pattern p = Pattern.compile(regex); - Matcher m = p.matcher(value); - - keysSet.add(key); - String chvalue; - while (m.find()) { - chvalue = m.group(1); - if (get(chvalue).equals(ErrorCycRef)) - return ErrorCycRef; - } map.put(key, value); - keysSet.remove(key); - return ""; } } public String get(String key) { synchronized (this) { + String regex = "\\$\\{(\\w+)\\}"; String value = map.get(key); if (value == null) return ""; @@ -38,23 +23,14 @@ public String get(String key) { Matcher m = p.matcher(value); while (m.find()) { - //Checking whether keys don't reference each other - if (keysSet.contains(m.group(1))) { - return ErrorCycRef; - } value = value.replaceFirst(regex, get(m.group(1))); m = p.matcher(value); } - //Adding whitespace after retrieved words - String regex2 = "\\w+"; - Pattern p2 = Pattern.compile(regex2); - Matcher m2 = p2.matcher(value); - if (m2.matches()) + if (!value.contains(" ")) value += " "; return value; } } - } diff --git a/src/test/java/ru/hh/school/stdlib/MultiConnection.java b/src/test/java/ru/hh/school/stdlib/MultiConnection.java index fee8580..34b7ec8 100644 --- a/src/test/java/ru/hh/school/stdlib/MultiConnection.java +++ b/src/test/java/ru/hh/school/stdlib/MultiConnection.java @@ -1,39 +1,39 @@ -package ru.hh.school.stdlib; - -import org.junit.Assert; -import org.junit.Test; - -import java.io.*; -import java.net.Socket; - -public class MultiConnection extends BaseFunctionalTest{ - - @Test - public void testMultiConnection() throws IOException{ - long timePeriod = 10000; - - Socket s1 = connect(); - Socket s2 = connect(); - - Writer out1 = new PrintWriter(s1.getOutputStream()); - BufferedReader in1 = new BufferedReader(new InputStreamReader(s1.getInputStream())); - Writer out2 = new PrintWriter(s2.getOutputStream()); - BufferedReader in2 = new BufferedReader(new InputStreamReader(s2.getInputStream())); - - out1.append("SET SLEEP " + timePeriod + "\n").flush(); - out2.append("SET SLEEP " + timePeriod + "\n").flush(); - long start = System.currentTimeMillis(); - out1.append("GET k1\n").flush(); - out2.append("GET k1\n").flush(); - Assert.assertEquals("", in1.readLine()); - Assert.assertEquals("VALUE", in1.readLine()); - Assert.assertEquals("", in1.readLine()); - Assert.assertEquals("", in2.readLine()); - Assert.assertEquals("VALUE", in2.readLine()); - Assert.assertEquals("", in2.readLine()); - long end = System.currentTimeMillis(); - - Assert.assertTrue((end - start) < (timePeriod * 2)); - System.out.println(end - start); - } -} +package ru.hh.school.stdlib; + +import org.junit.Assert; +import org.junit.Test; + +import java.io.*; +import java.net.Socket; + +public class MultiConnection extends BaseFunctionalTest { + + @Test + public void testMultiConnection() throws IOException { + long timePeriod = 10000; + + Socket s1 = connect(); + Socket s2 = connect(); + + Writer out1 = new PrintWriter(s1.getOutputStream()); + BufferedReader in1 = new BufferedReader(new InputStreamReader(s1.getInputStream())); + Writer out2 = new PrintWriter(s2.getOutputStream()); + BufferedReader in2 = new BufferedReader(new InputStreamReader(s2.getInputStream())); + + out1.append("SET SLEEP " + timePeriod + "\n").flush(); + out2.append("SET SLEEP " + timePeriod + "\n").flush(); + long start = System.currentTimeMillis(); + out1.append("GET k1\n").flush(); + out2.append("GET k1\n").flush(); + Assert.assertEquals("", in1.readLine()); + Assert.assertEquals("VALUE", in1.readLine()); + Assert.assertEquals("", in1.readLine()); + Assert.assertEquals("", in2.readLine()); + Assert.assertEquals("VALUE", in2.readLine()); + Assert.assertEquals("", in2.readLine()); + long end = System.currentTimeMillis(); + + Assert.assertTrue((end - start) < (timePeriod * 2)); + System.out.println(end - start); + } +} diff --git a/src/test/java/ru/hh/school/stdlib/Substitutor3000Test.java b/src/test/java/ru/hh/school/stdlib/Substitutor3000Test.java index f316921..06fa2bd 100644 --- a/src/test/java/ru/hh/school/stdlib/Substitutor3000Test.java +++ b/src/test/java/ru/hh/school/stdlib/Substitutor3000Test.java @@ -1,38 +1,40 @@ -package ru.hh.school.stdlib; - -import org.junit.Assert; -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")); - - sbst.put("a", "avril"); - sbst.put("keys2", "1: ${a}, 2: ${b}"); - Assert.assertEquals("1: avril , 2: ", sbst.get("keys2")); - - sbst.put("c3po", "human robot"); - sbst.put("r2d2", "wheel robot"); - sbst.put("keys3", "1: ${c3po}, 2: ${r2d2}"); - Assert.assertEquals("1: human robot, 2: wheel robot", sbst.get("keys3")); - - //Checking how cycle references are handled - sbst.put("r1","${r2}"); - sbst.put("r2","${r3}"); - Assert.assertTrue(("Error. Cycle reference.".equals(sbst.put("r3","${r1}")))); - } - - @Test - public void emptyReplacement() { - Substitutor3000 sbst = new Substitutor3000(); - sbst.put("k", "bla-${inexistent}-bla"); - - Assert.assertEquals("bla--bla", sbst.get("k")); - } -} +package ru.hh.school.stdlib; + +import org.junit.Assert; +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")); + + sbst.put("a", "avril"); + sbst.put("keys2", "1: ${a}, 2: ${b}"); + Assert.assertEquals("1: avril , 2: ", sbst.get("keys2")); + + sbst.put("c3po", "human robot"); + sbst.put("r2d2", "wheel robot"); + sbst.put("keys3", "1: ${c3po}, 2: ${r2d2}"); + Assert.assertEquals("1: human robot, 2: wheel robot", sbst.get("keys3")); + + /* + //Checking how cycle references are handled + sbst.put("r1","${r2}"); + sbst.put("r2","${r3}"); + Assert.assertTrue(("Error. Cycle reference.".equals(sbst.put("r3","${r1}")))); + */ + } + + @Test + public void emptyReplacement() { + Substitutor3000 sbst = new Substitutor3000(); + sbst.put("k", "bla-${inexistent}-bla"); + + Assert.assertEquals("bla--bla", sbst.get("k")); + } +} From 525f990bdd1078d5aefe9a003f92ece7961c1f2a Mon Sep 17 00:00:00 2001 From: Yuriy Khamzyaev Date: Wed, 18 Jan 2012 15:34:21 +0400 Subject: [PATCH 07/11] Added fixed recursive links handling --- .../hh/school/stdlib/RecursiveException.java | 4 + .../ru/hh/school/stdlib/ServerThread.java | 8 +- .../ru/hh/school/stdlib/Substitutor3000.java | 8 +- .../ru/hh/school/stdlib/MultiConnection.java | 5 +- .../ru/hh/school/stdlib/SimpleGetTest.java | 167 +++++++++--------- .../hh/school/stdlib/Substitutor3000Test.java | 21 ++- 6 files changed, 117 insertions(+), 96 deletions(-) create mode 100644 src/main/java/ru/hh/school/stdlib/RecursiveException.java diff --git a/src/main/java/ru/hh/school/stdlib/RecursiveException.java b/src/main/java/ru/hh/school/stdlib/RecursiveException.java new file mode 100644 index 0000000..9467771 --- /dev/null +++ b/src/main/java/ru/hh/school/stdlib/RecursiveException.java @@ -0,0 +1,4 @@ +package ru.hh.school.stdlib; + +public class RecursiveException extends Exception { +} diff --git a/src/main/java/ru/hh/school/stdlib/ServerThread.java b/src/main/java/ru/hh/school/stdlib/ServerThread.java index 7629e6f..35dee17 100644 --- a/src/main/java/ru/hh/school/stdlib/ServerThread.java +++ b/src/main/java/ru/hh/school/stdlib/ServerThread.java @@ -49,7 +49,13 @@ private String processInput(String inputLine) { if (command.equals("GET")) { sleep(); String key = tokenizer.nextToken(); - return "VALUE\n" + substitutor.get(key); + String value; + try { + value = substitutor.get(key); + } catch (RecursiveException e) { + return "ERROR\nRecursive link detected"; + } + return "VALUE\n" + value; } else if (command.equals("PUT")) { sleep(); diff --git a/src/main/java/ru/hh/school/stdlib/Substitutor3000.java b/src/main/java/ru/hh/school/stdlib/Substitutor3000.java index 74e8c52..f1e433b 100644 --- a/src/main/java/ru/hh/school/stdlib/Substitutor3000.java +++ b/src/main/java/ru/hh/school/stdlib/Substitutor3000.java @@ -6,6 +6,7 @@ public class Substitutor3000 { private Map map = Collections.synchronizedMap(new HashMap()); + private ArrayList keys = new ArrayList(); public void put(String key, String value) { synchronized (this) { @@ -13,7 +14,7 @@ public void put(String key, String value) { } } - public String get(String key) { + public String get(String key) throws RecursiveException { synchronized (this) { String regex = "\\$\\{(\\w+)\\}"; String value = map.get(key); @@ -22,11 +23,14 @@ public String get(String key) { Pattern p = Pattern.compile(regex); Matcher m = p.matcher(value); + if (keys.contains(value)) + throw new RecursiveException(); + keys.add(value); while (m.find()) { value = value.replaceFirst(regex, get(m.group(1))); m = p.matcher(value); } - + keys.remove(value); if (!value.contains(" ")) value += " "; diff --git a/src/test/java/ru/hh/school/stdlib/MultiConnection.java b/src/test/java/ru/hh/school/stdlib/MultiConnection.java index 34b7ec8..9f5498a 100644 --- a/src/test/java/ru/hh/school/stdlib/MultiConnection.java +++ b/src/test/java/ru/hh/school/stdlib/MultiConnection.java @@ -21,14 +21,13 @@ public void testMultiConnection() throws IOException { BufferedReader in2 = new BufferedReader(new InputStreamReader(s2.getInputStream())); out1.append("SET SLEEP " + timePeriod + "\n").flush(); - out2.append("SET SLEEP " + timePeriod + "\n").flush(); + Assert.assertEquals("OK", in1.readLine()); + Assert.assertEquals("connection closed", in1.readLine()); long start = System.currentTimeMillis(); out1.append("GET k1\n").flush(); out2.append("GET k1\n").flush(); - Assert.assertEquals("", in1.readLine()); Assert.assertEquals("VALUE", in1.readLine()); Assert.assertEquals("", in1.readLine()); - Assert.assertEquals("", in2.readLine()); Assert.assertEquals("VALUE", in2.readLine()); Assert.assertEquals("", in2.readLine()); long end = System.currentTimeMillis(); diff --git a/src/test/java/ru/hh/school/stdlib/SimpleGetTest.java b/src/test/java/ru/hh/school/stdlib/SimpleGetTest.java index 9db7885..e1b666c 100644 --- a/src/test/java/ru/hh/school/stdlib/SimpleGetTest.java +++ b/src/test/java/ru/hh/school/stdlib/SimpleGetTest.java @@ -1,83 +1,84 @@ -package ru.hh.school.stdlib; - -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(); - - Writer out = new PrintWriter(s.getOutputStream()); - out.append("GET k1\n").flush(); - BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream())); - - Assert.assertEquals("VALUE", in.readLine()); - Assert.assertEquals("", in.readLine()); - - out.append("PUT mo monday\n").flush(); - - Assert.assertEquals("OK", in.readLine()); - Assert.assertEquals("connection closed", in.readLine()); - - out.append("GET mo\n").flush(); - - Assert.assertEquals("VALUE", in.readLine()); - Assert.assertEquals("monday ", in.readLine()); - - out.append("PUT tu tuesday\n").flush(); - Assert.assertEquals("OK", in.readLine()); - Assert.assertEquals("connection closed", in.readLine()); - - out.append("PUT wed wednesday\n").flush(); - Assert.assertEquals("OK", in.readLine()); - Assert.assertEquals("connection closed", in.readLine()); - - out.append("PUT days1 ${mo} ${tu} ${wed}\n").flush(); - Assert.assertEquals("OK", in.readLine()); - Assert.assertEquals("connection closed", in.readLine()); - - out.append("PUT th thursday\n").flush(); - Assert.assertEquals("OK", in.readLine()); - Assert.assertEquals("connection closed", in.readLine()); - - out.append("PUT fr friday\n").flush(); - Assert.assertEquals("OK", in.readLine()); - Assert.assertEquals("connection closed", in.readLine()); - - out.append("PUT days2 ${th} ${fr}\n").flush(); - Assert.assertEquals("OK", in.readLine()); - Assert.assertEquals("connection closed", in.readLine()); - - out.append("PUT workdays ${days1} ${days2}\n").flush(); - Assert.assertEquals("OK", in.readLine()); - Assert.assertEquals("connection closed", in.readLine()); - - out.append("GET workdays\n").flush(); - Assert.assertEquals("VALUE", in.readLine()); - Assert.assertEquals("monday tuesday wednesday thursday friday ", in.readLine()); - - s.close(); - } - - @Test - public void testSleep() throws IOException { - long timePeriod = 1000; - Socket t = connect(); - Writer out = new PrintWriter(t.getOutputStream()); - BufferedReader in = new BufferedReader(new InputStreamReader(t.getInputStream())); - - out.append("SET SLEEP " + timePeriod + "\n").flush(); - long start = System.currentTimeMillis(); - out.append("GET k1\n").flush(); - Assert.assertEquals("", in.readLine()); - Assert.assertEquals("VALUE", in.readLine()); - Assert.assertEquals("", in.readLine()); - long end = System.currentTimeMillis(); - Assert.assertTrue(timePeriod - 100 < (end - start)); - Assert.assertTrue((end - start) < (timePeriod + 100)); - } -} +package ru.hh.school.stdlib; + +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(); + + Writer out = new PrintWriter(s.getOutputStream()); + out.append("GET k1\n").flush(); + BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream())); + + Assert.assertEquals("VALUE", in.readLine()); + Assert.assertEquals("", in.readLine()); + + out.append("PUT mo monday\n").flush(); + + Assert.assertEquals("OK", in.readLine()); + Assert.assertEquals("connection closed", in.readLine()); + + out.append("GET mo\n").flush(); + + Assert.assertEquals("VALUE", in.readLine()); + Assert.assertEquals("monday ", in.readLine()); + + out.append("PUT tu tuesday\n").flush(); + Assert.assertEquals("OK", in.readLine()); + Assert.assertEquals("connection closed", in.readLine()); + + out.append("PUT wed wednesday\n").flush(); + Assert.assertEquals("OK", in.readLine()); + Assert.assertEquals("connection closed", in.readLine()); + + out.append("PUT days1 ${mo} ${tu} ${wed}\n").flush(); + Assert.assertEquals("OK", in.readLine()); + Assert.assertEquals("connection closed", in.readLine()); + + out.append("PUT th thursday\n").flush(); + Assert.assertEquals("OK", in.readLine()); + Assert.assertEquals("connection closed", in.readLine()); + + out.append("PUT fr friday\n").flush(); + Assert.assertEquals("OK", in.readLine()); + Assert.assertEquals("connection closed", in.readLine()); + + out.append("PUT days2 ${th} ${fr}\n").flush(); + Assert.assertEquals("OK", in.readLine()); + Assert.assertEquals("connection closed", in.readLine()); + + out.append("PUT workdays ${days1} ${days2}\n").flush(); + Assert.assertEquals("OK", in.readLine()); + Assert.assertEquals("connection closed", in.readLine()); + + out.append("GET workdays\n").flush(); + Assert.assertEquals("VALUE", in.readLine()); + Assert.assertEquals("monday tuesday wednesday thursday friday ", in.readLine()); + + s.close(); + } + + @Test + public void testSleep() throws IOException { + long timePeriod = 1000; + Socket t = connect(); + Writer out = new PrintWriter(t.getOutputStream()); + BufferedReader in = new BufferedReader(new InputStreamReader(t.getInputStream())); + + out.append("SET SLEEP " + timePeriod + "\n").flush(); + Assert.assertEquals("OK", in.readLine()); + Assert.assertEquals("connection closed", in.readLine()); + long start = System.currentTimeMillis(); + out.append("GET k1\n").flush(); + Assert.assertEquals("VALUE", in.readLine()); + Assert.assertEquals("", in.readLine()); + long end = System.currentTimeMillis(); + Assert.assertTrue(timePeriod - 100 < (end - start)); + Assert.assertTrue((end - start) < (timePeriod + 100)); + } +} diff --git a/src/test/java/ru/hh/school/stdlib/Substitutor3000Test.java b/src/test/java/ru/hh/school/stdlib/Substitutor3000Test.java index 06fa2bd..109f8f0 100644 --- a/src/test/java/ru/hh/school/stdlib/Substitutor3000Test.java +++ b/src/test/java/ru/hh/school/stdlib/Substitutor3000Test.java @@ -6,11 +6,12 @@ public class Substitutor3000Test { @Test public void replacement() { + RecursiveException thrown = null; + try { 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")); sbst.put("a", "avril"); @@ -22,19 +23,25 @@ public void replacement() { sbst.put("keys3", "1: ${c3po}, 2: ${r2d2}"); Assert.assertEquals("1: human robot, 2: wheel robot", sbst.get("keys3")); - /* + //Checking how cycle references are handled sbst.put("r1","${r2}"); - sbst.put("r2","${r3}"); - Assert.assertTrue(("Error. Cycle reference.".equals(sbst.put("r3","${r1}")))); - */ + sbst.put("r2","${r1}"); + sbst.get("r1"); + } catch (RecursiveException e) { + thrown = e; + } + Assert.assertNotNull(thrown); } @Test public void emptyReplacement() { Substitutor3000 sbst = new Substitutor3000(); sbst.put("k", "bla-${inexistent}-bla"); - - Assert.assertEquals("bla--bla", sbst.get("k")); + try { + Assert.assertEquals("bla--bla ", sbst.get("k")); + } catch (RecursiveException e) { + System.out.println(e); + } } } From 54174c1172b5f60a2f221014513c53bb5dcc0568 Mon Sep 17 00:00:00 2001 From: Yuriy Khamzyaev Date: Wed, 18 Jan 2012 20:07:22 +0400 Subject: [PATCH 08/11] Final fixes --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ac574cc..0b55d3a 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ ${project.artifactId} - + gi ru.hh.school.stdlib.Launcher From 977d81ac5e1daed57b652d8fa0cc9de3d3a1717a Mon Sep 17 00:00:00 2001 From: Yuriy Khamzyaev Date: Fri, 27 Jan 2012 12:40:10 +0400 Subject: [PATCH 09/11] fixed: synchronized access to sleep time variable replaced StringTokenizer with regex fixed code errors --- pom.xml | 2 +- src/main/java/ru/hh/school/stdlib/Server.java | 10 ++++-- .../ru/hh/school/stdlib/ServerThread.java | 32 ++++++++++--------- .../ru/hh/school/stdlib/MultiConnection.java | 2 +- 4 files changed, 26 insertions(+), 20 deletions(-) diff --git a/pom.xml b/pom.xml index 0b55d3a..ac574cc 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ ${project.artifactId} - gi + ru.hh.school.stdlib.Launcher diff --git a/src/main/java/ru/hh/school/stdlib/Server.java b/src/main/java/ru/hh/school/stdlib/Server.java index d133add..f45dfe2 100644 --- a/src/main/java/ru/hh/school/stdlib/Server.java +++ b/src/main/java/ru/hh/school/stdlib/Server.java @@ -11,7 +11,7 @@ public class Server implements Runnable { private ServerSocket serverSocket = null; private Substitutor3000 substitutor; private int sleepTime = 0; - + public Server(InetSocketAddress addr) { this.serverPort = addr.getPort(); substitutor = new Substitutor3000(); @@ -44,10 +44,14 @@ private void openServerSocket() { } public int getSleepTime() { - return sleepTime; + synchronized (this) { + return sleepTime; + } } public void setSleepTime(int sleepTime) { - this.sleepTime = sleepTime; + synchronized (this) { + this.sleepTime = sleepTime; + } } } \ No newline at end of file diff --git a/src/main/java/ru/hh/school/stdlib/ServerThread.java b/src/main/java/ru/hh/school/stdlib/ServerThread.java index 35dee17..c790ca6 100644 --- a/src/main/java/ru/hh/school/stdlib/ServerThread.java +++ b/src/main/java/ru/hh/school/stdlib/ServerThread.java @@ -7,10 +7,13 @@ import java.net.Socket; import java.util.StringTokenizer; import java.util.concurrent.TimeUnit; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class ServerThread implements Runnable{ - private final static String WRONG_REQUEST ="Wrong request. Please try again."; private final static String SUCCESS_REQUEST = "OK\nconnection closed"; + private final static String WRONG_REQUEST = "ERROR\nWrong request. Please try again."; + private final static String RECURSIVE_ERROR = "ERROR\nRecursive link detected"; private Socket clientSocket; private Substitutor3000 substitutor; @@ -44,38 +47,37 @@ public void run() { } private String processInput(String inputLine) { - StringTokenizer tokenizer = new StringTokenizer(inputLine); - String command = tokenizer.nextToken(); - if (command.equals("GET")) { + String[] input = inputLine.split("\\s"); + + if (input[0].equals("GET")) { sleep(); - String key = tokenizer.nextToken(); + String key = input[1]; String value; try { value = substitutor.get(key); } catch (RecursiveException e) { - return "ERROR\nRecursive link detected"; + return RECURSIVE_ERROR; } return "VALUE\n" + value; } - else if (command.equals("PUT")) { + else if (input[0].equals("PUT")) { sleep(); - String key = tokenizer.nextToken(); + String key = input[1]; String value = ""; - while (tokenizer.hasMoreTokens()) { - value += tokenizer.nextToken(); - } + for (int i = 2; i < input.length; i++) + value += input[i]; substitutor.put(key, value); return SUCCESS_REQUEST; } - else if (command.equals("SET")) { - if (tokenizer.nextToken().equals("SLEEP")) { - server.setSleepTime(Integer.parseInt(tokenizer.nextToken())); + else if (input[0].equals("SET")) { + if (input[1].equals("SLEEP")) { + server.setSleepTime(Integer.parseInt(input[2])); return SUCCESS_REQUEST; } else return WRONG_REQUEST; } - else if (command.equals("EXIT")) { + else if (input[0].equals("EXIT")) { return "EXIT"; } else { diff --git a/src/test/java/ru/hh/school/stdlib/MultiConnection.java b/src/test/java/ru/hh/school/stdlib/MultiConnection.java index 9f5498a..628ee07 100644 --- a/src/test/java/ru/hh/school/stdlib/MultiConnection.java +++ b/src/test/java/ru/hh/school/stdlib/MultiConnection.java @@ -10,7 +10,7 @@ public class MultiConnection extends BaseFunctionalTest { @Test public void testMultiConnection() throws IOException { - long timePeriod = 10000; + long timePeriod = 2000; Socket s1 = connect(); Socket s2 = connect(); From 47e3451547326b0d98dd6f6377237e963ecf3984 Mon Sep 17 00:00:00 2001 From: Yuriy Khamzyaev Date: Thu, 2 Feb 2012 01:35:08 +0400 Subject: [PATCH 10/11] fixed imports --- src/main/java/ru/hh/school/stdlib/Launcher.java | 3 ++- src/main/java/ru/hh/school/stdlib/Server.java | 3 ++- src/main/java/ru/hh/school/stdlib/ServerThread.java | 3 --- src/main/java/ru/hh/school/stdlib/Substitutor3000.java | 5 ++++- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/main/java/ru/hh/school/stdlib/Launcher.java b/src/main/java/ru/hh/school/stdlib/Launcher.java index daff354..ab11d5d 100644 --- a/src/main/java/ru/hh/school/stdlib/Launcher.java +++ b/src/main/java/ru/hh/school/stdlib/Launcher.java @@ -2,7 +2,8 @@ import java.io.IOException; import java.net.InetSocketAddress; -import java.util.concurrent.*; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; public class Launcher { public static void main(String[] args) throws IOException { diff --git a/src/main/java/ru/hh/school/stdlib/Server.java b/src/main/java/ru/hh/school/stdlib/Server.java index f45dfe2..58250fa 100644 --- a/src/main/java/ru/hh/school/stdlib/Server.java +++ b/src/main/java/ru/hh/school/stdlib/Server.java @@ -4,7 +4,8 @@ import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; -import java.util.concurrent.*; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; public class Server implements Runnable { private int serverPort = 4444; diff --git a/src/main/java/ru/hh/school/stdlib/ServerThread.java b/src/main/java/ru/hh/school/stdlib/ServerThread.java index c790ca6..0ee2965 100644 --- a/src/main/java/ru/hh/school/stdlib/ServerThread.java +++ b/src/main/java/ru/hh/school/stdlib/ServerThread.java @@ -5,10 +5,7 @@ import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; -import java.util.StringTokenizer; import java.util.concurrent.TimeUnit; -import java.util.regex.Matcher; -import java.util.regex.Pattern; public class ServerThread implements Runnable{ private final static String SUCCESS_REQUEST = "OK\nconnection closed"; diff --git a/src/main/java/ru/hh/school/stdlib/Substitutor3000.java b/src/main/java/ru/hh/school/stdlib/Substitutor3000.java index f1e433b..5011793 100644 --- a/src/main/java/ru/hh/school/stdlib/Substitutor3000.java +++ b/src/main/java/ru/hh/school/stdlib/Substitutor3000.java @@ -1,6 +1,9 @@ package ru.hh.school.stdlib; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; From 8be8e4e342c9a377f2eca05b76aa917fa80dce69 Mon Sep 17 00:00:00 2001 From: Yuriy Khamzyaev Date: Fri, 3 Feb 2012 14:24:19 +0400 Subject: [PATCH 11/11] replaced usage of synchronized(this) by modifier synchronized in method declaration --- src/main/java/ru/hh/school/stdlib/Server.java | 12 ++--- .../ru/hh/school/stdlib/Substitutor3000.java | 44 +++++++++---------- 2 files changed, 24 insertions(+), 32 deletions(-) diff --git a/src/main/java/ru/hh/school/stdlib/Server.java b/src/main/java/ru/hh/school/stdlib/Server.java index 58250fa..2508d80 100644 --- a/src/main/java/ru/hh/school/stdlib/Server.java +++ b/src/main/java/ru/hh/school/stdlib/Server.java @@ -44,15 +44,11 @@ private void openServerSocket() { } } - public int getSleepTime() { - synchronized (this) { - return sleepTime; - } + public synchronized int getSleepTime() { + return sleepTime; } - public void setSleepTime(int sleepTime) { - synchronized (this) { - this.sleepTime = sleepTime; - } + public synchronized void setSleepTime(int sleepTime) { + this.sleepTime = sleepTime; } } \ No newline at end of file diff --git a/src/main/java/ru/hh/school/stdlib/Substitutor3000.java b/src/main/java/ru/hh/school/stdlib/Substitutor3000.java index 5011793..a414494 100644 --- a/src/main/java/ru/hh/school/stdlib/Substitutor3000.java +++ b/src/main/java/ru/hh/school/stdlib/Substitutor3000.java @@ -11,33 +11,29 @@ public class Substitutor3000 { private Map map = Collections.synchronizedMap(new HashMap()); private ArrayList keys = new ArrayList(); - public void put(String key, String value) { - synchronized (this) { - map.put(key, value); - } + public synchronized void put(String key, String value) { + map.put(key, value); } - public String get(String key) throws RecursiveException { - synchronized (this) { - String regex = "\\$\\{(\\w+)\\}"; - String value = map.get(key); - if (value == null) - return ""; - Pattern p = Pattern.compile(regex); - Matcher m = p.matcher(value); - - if (keys.contains(value)) - throw new RecursiveException(); - keys.add(value); - while (m.find()) { - value = value.replaceFirst(regex, get(m.group(1))); - m = p.matcher(value); - } - keys.remove(value); - if (!value.contains(" ")) - value += " "; + public synchronized String get(String key) throws RecursiveException { + String regex = "\\$\\{(\\w+)\\}"; + String value = map.get(key); + if (value == null) + return ""; + Pattern p = Pattern.compile(regex); + Matcher m = p.matcher(value); - return value; + if (keys.contains(value)) + throw new RecursiveException(); + keys.add(value); + while (m.find()) { + value = value.replaceFirst(regex, get(m.group(1))); + m = p.matcher(value); } + keys.remove(value); + if (!value.contains(" ")) + value += " "; + + return value; } }